Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are non-static class members destroyed even without a destructor?

In Bjarne Stroustrup's "The C++ Programming Language (4th edition)" in section 17.6 (Generating Default Operations) it mentions this:

If the programmer declares a copy operation, a move operation, or a destructor for a class, no copy operation, move operation, or destructor is generated for that class.

Thus, I'm confused why the SubObj destructor is called in this program:

#include <iostream>
using namespace std;

class SubObj {
    public:
        ~SubObj() {
            cout << "SubObj Destructor called" << endl;
        }
};

class Obj {
    private:
        SubObj so;

    public:
        Obj() {};
        Obj(const Obj& o) {};
};

int main() {
    Obj();
    cout << "Program end" << endl;
}

When compiling with g++ I get the following output:

$ ./a.out
SubObj Destructor called
Program end

Based on my understanding, I expected the default destructor for Obj to not be auto-generated because I defined a copy operation for Obj. And thus, I expected that the SubObj member of Obj would not be destroyed because there is no destructor for Obj.

Thus, I'm wondering: are object members automatically destroyed even without a destructor? Or is a destructor somehow being auto-generated for this example?

Edit:

Later in the book (17.6.3.4), when referring to an example, Bjarne mentions:

We defined copy assignment, so we must also define the destructor. That destructor can be =default because all it needs to do is to ensure that the member pos is destyored, which is what would have been done anyway had the copy assignment not been defined.

Based on the answers so far, it sounds appears as though Bjarne may have just been wrong on this one.

like image 852
johnnyodonnell Avatar asked Apr 23 '19 14:04

johnnyodonnell


People also ask

Can a static class have a destructor?

No, there isn't. A static destructor supposedly would run at the end of execution of a process. When a process dies, all memory/handles associated with it will get released by the operating system.

Which of the following statements is true about destructor?

Correct Answer : A destructor has no return type.

What is non static member?

A non-static member function is a function that is declared in a member specification of a class without a static or friend specifier. (

What happens when destructor is not called?

It is automatically called when an object is destroyed, either because its scope of existence has finished (for example, if it was defined as a local object within a function and the function ends) or because it is an object dynamically assigned and it is released using the operator delete.


3 Answers

That phrase from the book is poorly worded/wrong.

Of course a destructor is still generated if you provide a copy constructor. If it weren't, your program would not be able to be compiled.

If you provide your own destructor, a destructor is not generated. It doesn't need to be, and you can't have two.

Also, members are destroyed regardless of what your destructor does. A destructor allows you to do "extra" stuff, on top of the normal rules for object (and subobject) lifetime. There was never a risk that the SubObj member wouldn't be destroyed.

like image 161
Lightness Races in Orbit Avatar answered Oct 16 '22 16:10

Lightness Races in Orbit


Bjarne's wording could have been better here. What

If the programmer declares a copy operation, a move operation, or a destructor for a class, no copy operation, move operation, or destructor is generated for that class.

Could more accurately be (but is still wrong, see the link below for the full rules)

If the programmer declares a copy operation, a move operation, or a destructor for a class, no copy operation, move operation, or destructor (respectively) is generated for that class.

meaning if you declare any of those special member functions, the compiler will not add it's own version. If you declare a copy constructor, it does not stop the destructor, only the copy constructor (and move in C++11+). Only defining a destructors stops the compiler from generating one. To see all of the rules see: What are all the member-functions created by compiler for a class? Does that happen all the time?

like image 22
NathanOliver Avatar answered Oct 16 '22 15:10

NathanOliver


I do not have this book to check what is actually written here, but either you are quoting it incorrectly, or it is inaccurate (the latter is hard to believe). The other option is that it is just poorly phrased and confusing.

The only time when compiler will not generate an implicit destructor is when it is explicit:

If no user-declared destructor is provided for a class type (struct, class, or union), the compiler will always declare a destructor as an inline public member of its class.

https://en.cppreference.com/w/cpp/language/destructor

like image 33
SergeyA Avatar answered Oct 16 '22 16:10

SergeyA