I have got doubt when I was going through the code below. I.e why the destructor of derived class is not called even when an object of derived class goes out of scope in the code below:
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;
class ClassA
{
protected:
int width, height;
public:
void set_values(int x, int y)
{
width = x;
height = y;
}
virtual int area()
{
return 0;
}
~ClassA()
{
cout << "base class destructor called" << endl;
}
};
class ClassB : public ClassA
{
public :
int area()
{
return (width * height);
}
~ClassB()
{
cout << "derived class destructor called" << endl;
}
};
int main()
{
ClassA *Ptr = NULL;
ClassB Obj;
Ptr = &Obj;
Ptr->set_values(10, 20);
cout << Ptr->area() << endl;
delete Ptr;
return 0;
}
You should not call delete on Base class pointer pointing to derived class object unless the base class destructor is virtual else what you get is Undefined Behavior.
The destructor in base class needs to be marked virtual.
virtual ~ClassA(){}
Make your destructor virtual in base class. Otherwise, it calls base's destructor.
class ClassA
{
// ...
virtual ~ClassA()
{
cout << "base class destructor called" << endl;
}
};
Related
#include <iostream>
#include <memory>
using namespace std;
class Base
{
public:
virtual void foo() = 0;
protected:
int num{ 1 };
public:
Base() {
cout << "Base class constructor" << endl;
}
virtual ~Base()
{
cout << "Base class destructor " << endl;
}
private:
};
class Derive : public Base {
public:
Derive() {
cout << "Derive class constructor" << endl;
}
~Derive() {
cout << "Derive class destructor " << endl;
}
public:
void foo() override{
cout << "Derive class Foo function" << endl;
}
};
int main() {
unique_ptr<Base> b = make_unique<Base>(new Derive());
b->foo();
}
I get below error when I build this code.
in instantiation of function template specialization 'std::make_unique<Base, Derive *>' requested here unique_ptr b = make_unique(new Derive());
unimplemented pure virtual method 'foo' in 'Base' virtual void foo() = 0;
Does anyone know what is the reason of this error?
Note: I tried on https://godbolt.org/ and selected clang 11
In your main() function, do this instead:
unique_ptr<Base> b(new Derive());
This is because std::make_unique() takes the actual constructor arguments. You can't do that with polymorphism, but there's nothing wrong with directly instanstiating a std::unique_ptr directly with a heap allocated resource.
Do prefer std::make_unique() where it makes sense, though. This just isn't one of those cases.
I have an pure virtual base class and a derived class. I know I am allowed to implement a virtual (not pure) method in the base class.
What I do not understand is why I HAVE to also implement the same method in the derived class if what I want is simply to use the base implementation:
#include <iostream>
using namespace std;
class Abstract {
public:
int x;
Abstract(){
cout << "Abstract constructor" << endl;
x = 1;
}
virtual void foo() = 0;
virtual void bar(){
cout << "Abstract::bar" << endl;
}
};
class Derived : Abstract {
public:
int y;
Derived(int _y):Abstract(){
cout << "Derived constructor" << endl;
}
virtual void foo(){
cout << "Derived::foo" << endl;
}
virtual void bar(){
Abstract::bar();
}
};
int main()
{
cout << "Hello World" << endl;
Derived derived(2);
derived.foo();
derived.bar(); //HERE I HAVE TO DEFINE Derived::bar to use it
return 0;
}
You don’t have to do that. You can do the following:
class Derived : public Abstract {
That way, you can use the public methods from the base class.
As it is located at the title.
Here is example:
#include <iostream>
using namespace std;
class Base {
private:
int nSize;
public:
Base(){
cout << "I'm Base constructor" << endl;
}
};
class Derived : public Base {
int nMaxSize;
public:
Derived(){
cout << "I'm Derived constructor" << endl;
}
};
int main(){
Derived obj;
return 0;
}
The result:
I'm Base constructor
I'm Derived constructor
You have no choice. The best you can do is pass a flag to the base constructor disabling what you don't want. But this indicates bad design.
Why was destructor of Derived class called in this code?
#include <iostream>
class Base
{
public:
Base() { std::cout << "Base::Base() \n"; }
~Base() { std::cout << "Base::~Base() \n"; }
};
class Derived : public Base
{
public:
Derived() { std::cout << "Derived::Derived() \n"; }
~Derived() { std::cout << "Derived::~Derived() \n"; }
};
Derived foo() { return Derived(); }
int main()
{
const Derived& instance = foo();
}
Why was destructor of Derived class called in this code?
Because the Derived instance created in foo() is going out of scope at the end of main program.
#include <iostream>
using namespace std;
class Base {
public:
Base() {
std::cout << "Base::Base() \n";
}
~Base() {
std::cout << "Base::~Base() \n";
}
};
class Derived: public Base {
public:
int i;
Derived() {
i = 10;
std::cout << "Derived::Derived() \n";
}
~Derived() {
i = 0;
std::cout << "Derived::~Derived() \n";
}
int get() {
return i;
}
};
Derived foo() {
return Derived();
}
int main() {
const Derived& instance = foo();
cout << instance.i << endl;
return 0;
}
The output is as follows:
Base::Base()
Derived::Derived()
10
Derived::~Derived()
Base::~Base()
To make it more interesting, consider a modified main:
const Base& instance = foo();
That code creates a temporary (the object returned by foo) of type Derived and extends the lifetime of the object by binding it to a constant reference of type Base. The lifetime of the temporary will be extended until the reference goes out of scope at which point the object will get destroyed. The code is roughly translated to:
Derived __tmp = foo();
const Base& instance = __tmp;
At the end of the block holding the reference instance, the __tmp variable also goes out of scope and gets deleted. Note that even with no virtual destructor, the appropriate destructor is called, as __tmp is of type Derived (the type returned by the function).
hey there, why is the base destructor called twice at the end of this program?
#include <iostream>
using namespace std;
class B{
public:
B(){
cout << "BC" << endl; x = 0;
}
virtual ~B(){
cout << "BD" << endl;
}
void f(){
cout << "BF" << endl;
}
virtual void g(){
cout << "BG" << endl;
}
private:
int x;
};
class D: public B{
public:
D(){
cout << "dc" << endl; y = 0;
}
virtual ~D(){
cout << "dd" << endl;
}
void f(){
cout << "df" << endl;
}
virtual void g(){
cout << "dg" << endl;
}
private:
int y;
};
int main(){
B b, * bp = &b;
D d, * dp = &d;
bp->f();
bp->g();
bp = dp;
bp->f();
bp->g();
}
Destructors are called in order, as if they were unwinding the effects of the corresponding constructors. So, first the destructors of the derived objects, then the destructors of the base objects. And making the destructors virtual doesn't have any impact on calling / not calling the base class destructor.
Also to mention, your example could be simplified this way (this code also results in calling the base destructor twice and the derived destructor once):
struct A {
~A() {
// ...
}
};
struct B: A {
~B() {
// ...
}
};
int main() {
A a;
B b;
}
Once it is called for b and once for d
Note when destructor of D called it is automatically calls the destructor of B it is different from ordinary virtual functions. where you need explicitly call base class function to use it.