First, the C++ standard has no heap. It has the free store, and automatic storage.
Lets look at a concrete example that matches your theoretical one:
struct Bar { int x[100]; }
struct Foo {
Bar bq;
int x;
~Foo() {};
};
Bar bq
is a member variable of any Foo
instance. When you create a Foo
on the free store, its member variables are part of Foo
. If Foo
is standard layout (like above), you are basically guaranteed that its member variables are allocated in a linear buffer. Non standard layout objects can, in some theoretical compiler, have exotic layouts: but in practice they do not.
With the above Foo
, no default destructor is created. However, for every destructor of Foo
, the objects inside Foo
are destroyed after the body of Foo
's destructor is run. Note that destroying a pointer does nothing -- I mean the actual objects part of Foo
.
This isn't because the "default destructor that is automatically created" is called -- the default destructor is ~Foo() {}
, the same as what you defined. Rather, code automatically runs after the destructor finishes.
The only way to make Bar
's destructor not be called would be to make the data member not be Bar
. There are a few ways to do this, including creating a Bar
sized and aligned buffer of data then placement new
ing the Bar
.
However, while the destructor will not be called, the memory that Bar
exists within will be recycled by the free store when the Foo
Bar
exists in is recycled.
If you wanted Bar
to leak, you'd block Foo
from being returned to the free store. There is, however, no way to allocate a Foo
from the free store and return part of the Foo
to the free store -- you are only allowed to return all of it or none. You could choose to implement your own free store or your own manual heap with these properties, and nothing will stop you. You can even override new
and delete
so that your heap is used instead of the free store when someone does a Foo* foo = new Foo()
, and when someone does a delete foo
.
However, the amount of memory that the Foo
takes up is not within your control, nor the relative location of each member variable.