mercredi 18 mars 2015

Why does incomplete type of smart pointer data member and raw pointer data member have different behavior when their parent destruct?


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
}



Aucun commentaire:

Enregistrer un commentaire