Hlavní navigace

Názor ke článku Alokátory a operator new v C++ od Tomas Mark - Ahoj, snažil jsem se prokousat přes tento článek...

  • 26. 8. 2024 11:05

    Tomas Mark

    Ahoj, snažil jsem se prokousat přes tento článek a nakonec takto vypadá code, který můžete copy paste vyzkoušet.

    #include <cstddef>
    #include <iostream>
    
    // Rozhraní alokátoru
    class IRuntimeAlloc
    {
    public:
        virtual void *alloc(std::size_t objSize) = 0;
        virtual void dealloc(void *ptr, std::size_t objSize) = 0;
    };
    
    class DynObjectOld
    {
    public:
        // Standardní operátor new
        void *operator new(std::size_t sz)
        {
            std::cout << "Standard new\n";
            return ::operator new(sz);
        }
    
        // Přetížený operátor new s alokátorem
        void *operator new(std::size_t sz, IRuntimeAlloc &alloc)
        {
            std::cout << "Custom new with allocator\n";
            return alloc.alloc(sz);
        }
    
        // Standardní operátor delete
        void operator delete(void *ptr, std::size_t sz)
        {
            std::cout << "Standard delete\n";
            ::operator delete(ptr);
        }
    
        // Přetížený operátor delete s alokátorem
        void operator delete(void *ptr, IRuntimeAlloc &alloc)
        {
            std::cout << "Custom delete with allocator\n";
            alloc.dealloc(ptr, sizeof(DynObjectOld));
        }
    };
    
    class DynObjectAllocHelper
    {
    public:
        DynObjectAllocHelper(IRuntimeAlloc &alloc) : alloc(alloc), sz(0) {}
    
        IRuntimeAlloc &ref() const { return alloc; }
        void storeSize(std::size_t sz) const { this->sz = sz; }
        std::size_t getSize() const { return sz; }
    
    protected:
        IRuntimeAlloc &alloc;
        mutable std::size_t sz;
    };
    
    class DynObject
    {
    public:
        // Standardní operátor new
        void *operator new(std::size_t sz)
        {
            std::cout << "Standard new\n";
            return ::operator new(sz);
        }
    
        // Přetížený operátor new s alokátorem
        void *operator new(std::size_t sz, IRuntimeAlloc &alloc)
        {
            std::cout << "Custom new with allocator\n";
            return alloc.alloc(sz);
        }
    
        // Přetížený operátor new s pomocníkem
        void *operator new(std::size_t sz, const DynObjectAllocHelper &alloc)
        {
            std::cout << "Custom new with helper\n";
            void *ptr = alloc.ref().alloc(sz);
            alloc.storeSize(sz);
            return ptr;
        }
    
        // Standardní operátor delete
        void operator delete(void *ptr, std::size_t sz)
        {
            std::cout << "Standard delete\n";
            ::operator delete(ptr);
        }
    
        // Přetížený operátor delete s alokátorem
        void operator delete(void *ptr, IRuntimeAlloc &alloc)
        {
            std::cout << "Custom delete with allocator\n";
            alloc.dealloc(ptr, sizeof(DynObjectOld));
        }
    
        // Přetížený operátor delete s pomocníkem
        void operator delete(void *ptr, const DynObjectAllocHelper &alloc)
        {
            std::cout << "Custom delete with helper\n";
            alloc.ref().dealloc(ptr, alloc.getSize());
        }
    };
    
    class AllocInBuffer : public IRuntimeAlloc
    {
    public:
        AllocInBuffer(void *buffer, std::size_t size) : buffer(static_cast<char *>(buffer)), size(size), used(0) {}
    
        void *alloc(std::size_t objSize) override
        {
            if (used + objSize > size)
                return nullptr;
            void *ptr = buffer + used;
            used += objSize;
            return ptr;
        }
    
        void dealloc(void *ptr, std::size_t objSize) override
        {
            // Tento jednoduchý alokátor neumožňuje dealokaci jednotlivých objektů
            // Nicméně by mohl resetovat celý buffer
            std::cout << "Buffer deallocated\n";
        }
    
    private:
        char *buffer;
        std::size_t size;
        std::size_t used;
    };
    
    
    int main() {
        char buffer[256];
        AllocInBuffer bufalloc(buffer, sizeof(buffer));
    
        // Alokace objektu pomocí vlastního alokátoru
        DynObject* obj = new(bufalloc) DynObject;
    
        // Uvolnění objektu
        // delete obj; // vyvola vyjimku
        obj->DynObject::operator delete(obj, bufalloc);
    
        return 0;
    }