Strange (?) behavior with virtual keyword with g++ (Ubuntu) - c++

I was going through notes about virtual destructors and virtual functions. Now, when I tried to write a simple code to validate my learning,
#include <iostream>
using namespace std;
class Base{
public:
Base (){
cout << "Constructing base" <<endl;
}
void doSomething (){
cout << "inside void " << endl;
}
~Base (){
cout << "Destructing base" << endl;
}
};
class Derived : public Base{
public:
Derived(){
cout << "Constructing derived" << endl;
}
void doSomething (){
cout << "inside derived void " << endl;
}
~Derived(){
cout << "Destructing derived" << endl;
}
};
int main(){
Derived *d = new Derived();
d->doSomething();
delete d;
}
Shouldn't I expect an output like so:
Constructing base
Constructing derived
inside void
Destructing base
because I didn't use the virtual keyword for the destructors of both derived and base? Can you please explain virtual functions and virtual destructors in view of this sample?
I get this output:
Constructing base
Constructing derived
inside derived void
Destructing derived
Destructing base
I'm confused.
I use g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3 in Ubuntu 12.04.

You are getting the correct output.
Derived *d = new Derived();
d->doSomething();
It's calling the Derived class member function. For the runtime function call dispatch mechanism to work, you need to qualify the member functions with virtual keyword. Also you should write -
Base *d = new Derived();
In the above case, static type of d is different from the dynamic type. So, derived class member function will be called at runtime. Also, Base class destructor should be virtual in such scenario.

Related

Virtual destructor, what would happen I didnt have a destructor in the derived class?

I've just had my lesson about virtual destructors and I have a question.
Lets say we have this code below:
#include <iostream>
class Base {
public:
virtual void fun() { std::cout << "Base Fun" << std::endl; };
virtual ~Base() { std::cout << "Base Destructor called" << std::endl; };
};
class Derived : public Base {
public:
virtual void fun() { std::cout << "Derived Fun" << std::endl; };
~Derived() { std::cout << "Derived Destructor called" << std::endl; };
};
int main()
{
Base* b = new Base();
Base* d = new Derived();
b->fun();
d->fun();
delete b;
delete d;
return 0;
}
We see that we have a Virtual destructor in our Base clase, which means when we delete d in our main, both the Base class destructor will be called and the Derived class destructor will be called..
**But what if we didnt have a destructor in our derived class, and we still wanted had the virtual destructor + we still wanted to delete d. What happens then? Does the derived class automatically "create" a destructor, and would the destructor then handle the ressource - d and delete it?
All classes have a destructor. If you don't write one explicitly, then compiler will implicitly generate it. Thus the case you are asking about "if I didn't have a destructor" doesn't exist.
and would the whole program still work as earlier?
It would work but not quite the same way since the implicitly generated destructor wouldn't print the string that your destructor prints.

Calling a virtual function from a destructor of a derived class in c++

Here is a snippet of my c++ code
class A {
public:
virtual void method() {
cout << "A::method" << endl;
}
virtual ~A() {
cout << "A::destructor" << endl;
}
};
class B : public A {
public:
virtual void method() {
cout << "B::method" << endl;
}
virtual ~B() {
cout << "B::destructor" << endl;
method();
}
};
int _tmain()
{
A* a = new B();
a->method();
delete a;
return 0;
}
I've learned that it's not preferable to call any virtual functions from constructors or destructors.
In the destructor of the derived class B, I call the virtual function named, "method()".
Here is the output message.
B::method
B::destructor
B::method
A::destructor
It seems to me there is no problem at all. The virtual function knows its object type and printed
"B::method()". Is this a kind of undefined behavior that should be avoided?
Conceptually all the virtual functions in B are accessible in the destructor body, so your code is fine and well-defined as it is.
But your code is extremely brittle: it would be a different matter if there was a child class of B which had method overridden. In that case writing B::method(); in the destructor body of B would be sufficient.
Short answer: calling virtual methods in constructors and destructors is best avoided.

How to execute a virtual function from a base class without the explicit call of Base::func() in a derived class?

I'm a newbie in C++ and have a question. I can't find any related stuff for this question on Google.
Is it possible in C++ for code in a virtual function to be called from the base class without invoking it with Base::func() in the derived class?
Here is an example of what I mean:
class Base {
public:
virtual void func(void) { cout << "Base func()" << endl; }
};
class Derived : Base {
public:
virtual void func(void) { cout << "Derived func()" << endl; }
};
The output should be the following when the function func is called from Derived:
Base func()
Derived func()
Is this even possible in C++? Or, is there another way to implement this behavior?
Is that intention even possible in C++? Or is there a other way to implement this behavior in C++?
You can get that behavior only if you add
Base::func();
in the implementation of Derived::func(). The language does not provide a mechanism to make that automatic.
You can make the base class get the calls first by making the interface non-virtual, and then call the (private) derived function from there:
class Base {
public:
void func()
{
cout << "Base func()" << endl;
derived_func();
}
private:
virtual void derived_func() { }
};
class Derived : Base {
private:
virtual void derived_func() { cout << "Derived func()" << endl; }
};
You have call the base class in derived class implementation to make that happen
class Base {
public:
virtual void func(void) { cout << "Base func()" << endl; }
};
class Derived : Base {
public:
virtual void func(void)
{
Base::function();
cout << "Derived func()" << endl;
}
};
But this is still calling Base::func() from Derived::func()
You can, however, achieve what you want if the func() was actually your constructor.

When I use dynamic_cast and delete the object delete , how the destructor works?

I create a object of derived class and a base class point for it ,
and then I use the dynamic_cast convert base class point to derived class point .
I delete the derived class point , but the program calls the derived destructor and the base destructor. Why does the program call the base destructor? After all, the base destructor isn't a virtual function....
#include<iostream>
#include<stdlib.h>
using namespace std;
class con {
private:
double num;
public:
con() {
num = 0;
cout << "default..." << endl;
}
void getnum() {
cout << num << endl;
}
};
class base {
public:
virtual void A() {
cout << "it is base A" << endl;
}
void B() {
cout << "it is base B" << endl;
}
~base() {
cout << "it is base decon" << endl;
}
};
class child : public base {
public:
void A() {
cout << "it is child A" << endl;
}
void B() {
cout << "it is child B" << endl;
}
~child() {
cout << "it is child decon" << endl;
}
};
int main(int argc, char** argv) {
base* b = new child();
child* c = dynamic_cast<child*>(b);
delete c; //the program print "it is child decon" "it is base decon"
getchar();
return 0;
}
Case 1: If you delete a pointer derived class, it always calls the destructor of the derived class first, then the destructor of the base class.
Case 2: If you delete a pointer to the base class of a derived class with a non-virtual base class destructor, it doesn't know about the derived class so it just deletes the base class.
Case 3: If you delete a pointer to the base class of a derived class with a virtual base class destructor, it uses virtual dispatch to the destructor of the derived class, then calls the destructor of the base class.
Case 2 is bad. It can cause resource leaks, etc. It should be avoided by always declaring destructors virtual in classes that are intended to be base classes.
Your example illustrates case 1.
If you want to see case 2 in action try delete b rather than delete c in your example.
Destructors in C++ don't "overload" as such; they chain up. When you say
{
child c;
}
then at the closing brace the compiler will insert a call to ~child(), which will in turn call ~base() (and the destructors of other base classes, if you had them). This is essential to avoid memory leaks -- otherwise how would base's members be destroyed? Note that this doesn't require the base destructor to be virtual.
This works the same way when you manually destroy something with delete:
child* c = new child{};
delete c; // runs ~child(), which calls ~base()
again, this doesn't require the destructor to be virtual.
What a virtual destructor does do is allow you to destroy a variable with dynamic type child using a pointer to a base, i.e.
child* c = new child{}
base* b = c;
delete b; // Will call ~child() if destructor is virtual, otherwise ~base()

Base class destructor is not virtual and child class destructor is virtual, program crash

Why does the following program crash? I have a base class whose destructor is not virtual but the child class destructor is virtual:
#include <iostream>
class Base {
public:
Base() {
std::cout << "Base::Base CTOR " << std::endl;
}
~Base() {
std::cout << "Base::Base DTOR " << std::endl;
}
};
class Child : public Base {
public:
Child(){
std::cout << "Child::Child CTOR " << std::endl;
}
virtual ~Child() {
std::cout << "Child::Child DTOR " << std::endl;
}
};
int main (int argc, char **argv) {
Base *ptr = new Child;
delete ptr;
}
What you are observing is called "undefined behavior". Make Base's dtor virtual if you want do call delete on Child instance through Base pointer.
From the 2003 standard, 5.3.5/3:
In the first alternative (delete object), if the static type of the
operand is different from its dynamic type, the static type shall be a
base class of the operand’s dynamic type and the static type shall
have a virtual destructor or the behavior is undefined.
You have undefined behavior because the static type of the pointer operand to delete does not match the dynamic type of the object that it points to and you don't meet the requirements for the exception to this rule that allows passing a pointer to a base class to the object being deleted because this exception requires the base class to have a virtual destructor.
Any behaviour is possible including the code working "as expected" or a crash.
Hope this example helps you get the point:
#include <iostream>
class Base {
public:
Base() {
std::cout << "Base::Base CTOR " << std::endl;
}
~Base() {
std::cout << "Base::Base DTOR " << std::endl;
}
private:
protected:
};
class Child : public Base {
public:
Child(){
std::cout << "Child::Child CTOR " << std::endl;
}
~Child(){
std::cout << "Child::Child DTOR " << std::endl;
}
private:
protected:
};
class gChild : public Child {
public:
gChild(){
std::cout << "Child::Child gCTOR " << std::endl;
}
~gChild(){
std::cout << "Child::Child gDTOR " << std::endl;
}
private:
protected:
};
int main ( int argc, char **argv) {
Base *ptr = new gChild;
delete ptr;
}
if virtual ~Base() ,then all destructors' print gets printed.
if virtual ~child() or virtual ~gChild(),only base destructor gets printed.
It's because the destructors executes in opposite direction.and here behaviour is undefined.You must define the base destructor virtual to get the expected result.
Thanks.
Just look at this:
#include <iostream>
class Base
{
public:
void nonvirtualmethod()
{ std::cout << "Base nonvirtualmethod" << std::endl; }
virtual void virtualmethod()
{ std::cout << "Base virtualmethod" << std::endl; }
};
class Derived: public Base
{
public:
void nonvirtualmethod()
{ std::cout << "Derived nonvirtualmethod" << std::endl; }
virtual void virtualmethod()
{ std::cout << "Derived virtualmethod" << std::endl; }
};
int main()
{
Derived d;
Derived* pd = &d;
Base* pb = &d; //< NOTE: both pd and pb point to the same object
pd->nonvirtualmethod();
pb->nonvirtualmethod();
pd->virtualmethod();
pb->virtualmethod();
}
I gives you the following output:
Derived nonvirtualmethod
Base nonvirtualmethod
Derived virtualmethod
Derived virtualmethod //< invoked by a Base*
This is because there is a difference between the static type of the pb pointer (Base*)
and the dynamic type it points to (Derived).
The difference between virtual and plain methods is that non-virtual methods follow the the static type mapping (so a Base pointer invokes Base::methods), while virtual methods follow the chain of the runtime types, hence if a Base* points to a Derived, the Derived method will be called.
Destructors, in this sense, are nothing special: if it is not virtual, a Base pointer will not invoke the Derived one, hence you are left with an half-destroyed object, that is given back to the memory store.
The reason why this is UB (and not simply denied), is because the "memory store" is not managed by the language itself, but from the platform the program is hosted in: the crash most likely depends on the fact that the missing of the Derived part (still alive) will result in the operating system trying free a block of memory with a wrong starting address.