Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are dynamic objects of a type with a deleted destructor constructed?

Let's say I have something that looks like this:

struct foo {
    ~foo() = delete;
}

And let's say I later dynamically allocate an object of type foo:

foo *f = new foo;

This is fine; I assume the synthesized default constructor is used to construct the object denoted by f, however:

foo f2;

Gives me an error:

Attempt to use a deleted function

So how is the object denoted by f constructed if the default constructor for foo is implicitly deleted?

Moreover, assuming foo has the private member size_t n. What is the value of n for a dynamically allocated foo, such as the one denoted by f?

like image 1000
Alt-Rock Ninja Cowgirl Avatar asked Mar 01 '16 18:03

Alt-Rock Ninja Cowgirl


People also ask

How do you create and delete dynamic objects in C++?

C++ supports two operators new and delete to perform memory allocation and de-allocation. These types of objects are called dynamic objects. The new operator is used to create objects dynamically and the delete operator is used to delete objects dynamically. The dynamic objects can be created with the help of pointers.

At which point does a destructor of a dynamically allocated class object get called?

A class' destructor is called whenever an object of the class goes out of scope.

When an object is destroyed destructor is automatically called?

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 . A destructor has the same name as the class, preceded by a tilde ( ~ ).

Which is the C++ operator that calls the destructor to deallocate memory of dynamic objects?

Using the delete operator on an object deallocates its memory.


1 Answers

When you write

foo f;

The compiler needs to be able to construct f when it's initially created. Since that variable has automatic storage duration (the fancy C++ term for "on the stack"), the compiler is responsible for generating code to clean it up as well. That requires access to a destructor, but since you've deleted it, you get an error.

When you write

foo* f = new foo;

You're creating a pointer to a foo object on the stack, and the compiler can destroy the pointer itself without access to the foo destructor. On the other hand, the object created with new foo has dynamic storage duration, meaning that you promise to manually destroy it. Consequently, the compiler doesn't need to access the destructor, so the creation step is fine. That said, if you then write

delete f;

You should get an error because that operation does need the destructor.

EDIT: From your follow-up, my sense is that you're wondering why the default constructor still is generated even though the destructor is deleted. I have a draft of the C++14 spec and in §12.1.4, it says the following:

A default constructor for a class X is a constructor of class X that can be called without an argument. If there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared as defaulted (8.4). An implicitly-declared default constructor is an inline public member of its class. A defaulted default constructor for class X is defined as deleted if:

— X is a union-like class that has a variant member with a non-trivial default constructor,

— any non-static data member with no brace-or-equal-initializer is of reference type,

— any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or- equal-initializer does not have a user-provided default constructor,

— X is a union and all of its variant members are of const-qualified type (or array thereof),

— X is a non-union class and all members of any anonymous union member are of const-qualified type (or array thereof),

— any direct or virtual base class, or non-static data member with no brace-or-equal-initializer, has class type M (or array thereof) and either M has no default constructor or overload resolution (13.3) as applied to M’s default constructor results in an ambiguity or in a function that is deleted or inaccessible from the defaulted default constructor, or

— any direct or virtual base class or non-static data member has a type with a destructor that is deleted or inaccessible from the defaulted default constructor.

In other words, the deletion of a destructor has no effect on the autogeneration of a default constructor.

like image 50
templatetypedef Avatar answered Sep 27 '22 22:09

templatetypedef