Is the behavior defined correctly to save the destructor address of the object and call it later?

I am currently working on a Stack Allocator written in C ++. It should be possible to get objects from this Stack Allocator using the template method. These objects must be destroyed after calling another deletion method. When I experimented with different approaches to calling the destructor, I came across the following:

auto destructor = someObject->~SomeClass;
destructor();

The destructor is apparently called the caller, but to me it looks weird. I have the following questions:

  • Is this a clearly defined behavior?
  • What type of destructor (with which can I replace the auto keyword)?
  • Can I save all the addresses of destructors of several objects of different types in the list and call them later?
+4
source share
2 answers

Can I save all the addresses of destructors of several objects of different types in the list and call them later?

Yes. Note that my solution also saves a pointer to the destroyed object, not just the destructor. you can do a little lambda magic to achieve this + a little low level help:

class GenericDestructor {

private:    
    const void* object;
    void(*destructor)(const void*);

public:

    template<class T>
    GenericDestructor(const T& _object) noexcept :
        object(std::addressof(_object)){

        destructor = [](const void* _object) {
            auto original = static_cast<const T*>(_object);
            original->~T();
        };

    };

    void operator () () noexcept {
        destructor(object);
    }

};

storage:

std::vector<GenericDestructor> storedDestructors;
auto needsToBeDeleted = new std::string();
storedDestructors.emplace_back(*needsToBeDeleted);

destruction of all saved objects:

for(auto& storedDestructor : storedDestructors) storedDestructor();
+1
source

As noted in the comments, this is the Undefined Behavior / Compiler extension.

You can do what you want:

template<typename T>
std::function<void(T*)> defer_dtor()
{
   return [](T* ptr) {ptr->~T();};
}

or directly (more like your question, but the unique lambda type cannot be added directly to the list.)

auto destructor = [&]{someObject->~SomeClass();};
destructor();

: delete ptr. , , , delete ptr, std::shared_ptr.

[] : " ".

. , . ? , virtual. , ? , ->~Type() ?

+3

Source: https://habr.com/ru/post/1675103/


All Articles