In the following code:
smart pointer data member pImpl(class Impl) and raw pointer pc(class CAT) all are incomplete data type, there is no definition of these two classes in Widget.h
//widget.h
#ifndef W_H_
#define W_H_
#include <memory>
class Widget {
public:
Widget();
~Widget() { //
delete pc; // I know I should put ~Widget to .cpp
// I just want to show the difference in behavior
// between raw pointer and smart pointer(both has incomplete type)
// when widget object destructs
}
private:
struct Impl;
std::shared_ptr<Impl> pImpl; // use smart pointer
struct CAT;
CAT *pc; //raw pointer
};
#endif
//widget.cpp
#include "widget.h"
#include <string>
#include <vector>
#include <iostream>
using namespace std;
struct Widget::CAT
{
std::string name;
CAT(){cout<<"CAT"<<endl;}
~CAT(){cout<<"~CAT"<<endl;}
};
struct Widget::Impl {
std::string name;
Impl(){cout<<"Impl"<<endl;}
~Impl(){cout<<"~Impl"<<endl;}
};
Widget::Widget()
: pImpl(std::make_shared<Impl>()),
pc(new CAT)
{}
//main.cpp
#include "widget.h"
int main()
{
Widget w;
}
//output
Impl
CAT
~Impl
For the raw pointer data member, its destuctor is not called when widget object is destructed.
While the shared_ptr
data member, its destructor has been correctly called.
To my understanding, in Widget::~Widget() it should generate some code automatically as the following:
~Widget() {
delete pc; // wrote by me
// generated by compiler
delete pImpl->get();
}
Why do shared_ptr data member and raw data member have different behavior when the widget gets destructed?
I test the code using g++4.8.2 in Linux
================================EDIT=============================== According to the answers, the reason is because of :
the code generated by compiler is NOT:
~Widget() {
delete pc; // wrote by me
// generated by compiler
delete pImpl->get();
}
it maybe something like:
~Widget() {
delete pc; // wrote by me
// generated by compiler
pimpl.deleter(); //deleter will be initailized while pimpl object is initialized
}