On 08.10.2016 01:02, JiiPee wrote:
> Maybe a simple question, but just ensuring that understanding 100%.
>
> If I create a Circle like this:
>
> class Shape
> {
> public:
> ~Shape();
> int a;
> };
>
> class Circle: public Shape
> {
> public:
> ~Shape();
> int b;
> };
>
> Then:
> Shape* s = new Circle();
> delete s;
>
> now Shape destructor should be virtual obviously. But what happens if I
> do not make it virtual: does int b; be deleted?
Formally it's Undefined Behavior, and that means that anything or
nothing may happen.
In practice a compiler is unlikely to detect the UB and then make the
program do Nasty Things™ in that case.
Instead the ordinary code for a `delete` expression is likely to be
executed, under the invalid assumption that the object to be deleted is
of most derived class `Shape`. Since a `Shape` object is of smaller size
than the actual `Circle` object, this might foul up things with respect
to the memory allocator. Or not: it depends on how the implementation
stores the sizes of allocated objects, or not, and it depends on whether
the memory block that would have been allocated for a `Shape` would be
the same size as for a `Circle`.
In the common case where it's the memory manager that keeps track of
block size for all dynamically allocated objects, the code is likely to
just work.
That is one possible effect of Undefined Behavior.
> Am I correct that when
> creating s (s = new Circle();) then it consists of two parts: Shape part
> and Circle part and they are separate "units".
They're not separate: they're very much adjoined, and in some cases
parts of a derived class may be intermingled with parts of a base class.
> So when I destroy s only
> the Shape part of the object will be destroyed but all the Circle part
> will stay in memory (leaks)? is this how it is?
No no no. :)
There's one allocated block of memory. It may or may not be correctly
dellocated, depending on the C++ implementation. Before that only the
`Shape` destructor will be executed, since it's not virtual.
Cheers & hth.,
- Alf