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
?
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.
A class' destructor is called whenever an object of the class goes out of scope.
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 ( ~ ).
Using the delete operator on an object deallocates its memory.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With