Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is explicitly calling constructors and destructors safe, according to the C++ standard?

Some developers call constructors and destructors explicitly for some workarounds. I know, it is not a good practice, but it seems it is done to realize some scenarios.

For example, in this article, Beautiful Native Libraries, the author uses this technique.

In the code below, at the end, it can be seen that the constructor is called explicitly:

#include <limits>

template <class T>
struct proxy_allocator {
    typedef size_t size_type;
    typedef ptrdiff_t difference_type;
    typedef T *pointer;
    typedef const T *const_pointer;
    typedef T& reference;
    typedef const T &const_reference;
    typedef T value_type;

    template <class U>
    struct rebind {
        typedef proxy_allocator<U> other;
    };

    proxy_allocator() throw() {}
    proxy_allocator(const proxy_allocator &) throw() {}
    template <class U>
    proxy_allocator(const proxy_allocator<U> &) throw() {}
    ~proxy_allocator() throw() {}

    pointer address(reference x) const { return &x; }
    const_pointer address(const_reference x) const { return &x; }

    pointer allocate(size_type s, void const * = 0) {
        return s ? reinterpret_cast<pointer>(yl_malloc(s * sizeof(T))) : 0;
    }

    void deallocate(pointer p, size_type) {
        yl_free(p);
    }

    size_type max_size() const throw() {
        return std::numeric_limits<size_t>::max() / sizeof(T);
    }

    void construct(pointer p, const T& val) {
        new (reinterpret_cast<void *>(p)) T(val);
    }

    void destroy(pointer p) {
        p->~T();
    }

    bool operator==(const proxy_allocator<T> &other) const {
        return true;
    }

    bool operator!=(const proxy_allocator<T> &other) const {
        return false;
    }
};

For some scenarios like this, it can be necessary to call constructors and destructors explicitly, but what does the standard say: is it undefined behavior, is it unspecified behavior, is it implementation defined behavior, or is it well defined?

like image 864
mustafagonul Avatar asked Feb 29 '16 07:02

mustafagonul


People also ask

How are constructors called explicitly?

Explicit use of the this() or super() keywords allows you to call a non-default constructor. To call a non-args default constructor or an overloaded constructor from within the same class, use the this() keyword. To call a non-default superclass constructor from a subclass, use the super() keyword.

Do you have to call a destructor?

No. You never need to explicitly call a destructor (except with placement new ). A class's destructor (whether or not you explicitly define one) automagically invokes the destructors for member objects. They are destroyed in the reverse order they appear within the declaration for the class.

Are destructors called automatically C++?

A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to delete .

What are the rules which has to followed while writing constructor and destructor?

1) Name should begin with tilde sign(~) and must match class name. 2) There cannot be more than one destructor in a class. 3) Unlike constructors that can have parameters, destructors do not allow any parameter. 4) They do not have any return type, just like constructors.

Is it possible to call constructor and destructor explicitly in C++?

- GeeksforGeeks Is it possible to call constructor and destructor explicitly in C++? A constructor is a special member function that is automatically called by the compiler when an object is created and the destructor is also a special member function that is also implicitly called by the compiler when the object goes out of scope.

What are destructors&constructors in Java?

Destructors are used to clean up resources used by the object. What are Constructors & Destructors? The constructor is a special method of the class that is called when a class is instantiated. Destructor is opposite of constructor. It is a special method of the class that is invoked when a class object goes out of scope.

What is the use of constructor in C++?

C++ provides a special member function called the constructor which enables an object to initialize itself when it is created. This is known as automatic initialization of objects. It also provides another member function called the destructor that destroys the objects when they are no longer required.

What is the difference between copy constructor and destructor?

There is a concept of copy constructor which is used to initialize a object from another object. Syntax: ClassName() { //Constructor's Body } Destructor: Like constructor, deconstructor is also a member function of a class that has the same name as the class name preceded by a tilde(~) operator.


1 Answers

Yes it is supported and well defined, it is safe.

new (reinterpret_cast<void *>(p)) T(val);

Is called the placement new syntax and is used to construct an object at a specific memory location, the default behaviour; such as required in the allocator posted. If the placement new is overloaded for the specific type T, then it would be called instead of the global placement new.

The only way to destruct such a constructed object is to explicitly call the destructor p->~T();.

The use of the placement new and explicit destruction does require/allow that the code implemented controls the lifetime of the object - the compiler offers little assistance in this case; thus is it important that the objects are constructed in well aligned and sufficiently allocated locations. Their use is often found in allocators, such as in the OP, and the std::allocator.

like image 81
Niall Avatar answered Oct 25 '22 10:10

Niall