The following code
struct Base
{
public:
Base()
{
std::cout<<"Base Ctr";
}
~Base()
{
std::cout<<"Base Dtr";
}
};
struct Derived : Base
{
Derived()
{
std::cout<<"Derived Ctr";
}
~Base()
{
std::cout<<"Derived Dtr";
}
};
int main()
{
Base* b = new Derived;
delete b;
}
gives me the following output :
Base Ctr
Derived Ctr
Base Dtr
The solution to this is to make the base destructor virtual.
However when I use boost smart pointers without virtual base destructor. I get a different output.
int main()
{
boost::shared_ptr<Base> b = boost::make_shared<Derived>();
}
The output is
Base Ctr
Derived Ctr
Derived Dtr
Base Dtr
How is boost shared_ptr able to achieve this without affecting(I'm assuming) the Base and Derived classes.
How does it scale it for multiple level inheritance, i.e base points to dervderv
where dervderv is inherited from derv.
EDIT:
Most answers tell me that the "magic" happens in make_shared. I however get the same behaviour for the following code
boost::shared_ptr<Base> ptr(new Derived);
A solution implemented using normal function pointers:
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <typeinfo>
using namespace std;
struct Base{
Base(){
cout<<"Base ctor."<<endl;
}
~Base(){
cout<<"Base dtor."<<endl;
}
};
struct Derv: Base{
Derv():Base(){
cout<<"Derv ctor."<<endl;
}
~Derv(){
cout<<"Derv dtor."<<endl;
}
};
typedef void (*DEL)(void*);
template<typename U>
void deleter(void* ptr)
{
delete static_cast<U*>(ptr);
}
template<typename T>
struct SmartPtr{
T* memPtr;
DEL func;
template<typename U>
SmartPtr(U* p):
memPtr(p)
{
func = deleter<U>;
}
~SmartPtr(){
func(memPtr);
}
};
int main()
{
//case 1
SmartPtr<Base> ptrSmart1(new Derv());
//case 2
SmartPtr<Base> ptrSmart2(new Base());
//case 3
SmartPtr<Derv> ptrSmart3(new Derv());
return 0;
}