提升共享指针构造函数析构函数
boost shared pointer constructor destructor
以下代码
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;
}
给我以下输出:
Base Ctr
Derived Ctr
Base Dtr
解决这个问题的方法是使基本析构函数成为虚拟的。
但是,当我使用没有虚拟基析构函数的 boost 智能指针时。我得到了不同的输出。
int main()
{
boost::shared_ptr<Base> b = boost::make_shared<Derived>();
}
输出为
Base Ctr
Derived Ctr
Derived Dtr
Base Dtr
boost shared_ptr 如何在不影响(我假设)Base 和 Derived 类.
的情况下实现这一点
它如何为多级继承扩展它,即基点到 dervderv
其中dervderv继承自derv.
编辑:
大多数答案告诉我 "magic" 发生在 make_shared 中。然而,我对以下代码得到了相同的行为
boost::shared_ptr<Base> ptr(new Derived);
Boost 通过删除函子实现了这一点。默认实现在使用 make_shared
.
创建的类型上调用 delete
简而言之,boost::smart_ptr
包含指向对象的指针、引用计数和一个在析构函数中调用的删除函数,当您调用boost::make_shared<Derived>()
时,它将创建[的默认构造对象=25=] Derived
并且 deleter 将指向 Derived
的析构函数。这应该适用于任何长度的继承链,但在基 class 中具有虚拟析构函数确实是强制性的。
考虑这种技术的下一个简化的简单示例实现:
#include <iostream>
#include <functional>
using namespace std;
struct Base
{
public:
Base()
{
std::cout<<"Base Ctr ";
}
~Base()
{
std::cout<<"Base Dtr ";
}
};
struct Derived : Base
{
Derived()
{
std::cout<<"Derived Ctr ";
}
Derived(const Derived& d)
{
std::cout<<"Derived copy Ctr ";
}
~Derived()
{
std::cout<<"Derived Dtr ";
}
};
template <typename T>
void default_deleter(T* p) {
delete p;
}
template <typename T>
struct pointer {
pointer(T* p, std::function<void ()> d) : p_(p), deleter_(d) {}
template <typename U>
pointer(pointer<U> other) : p_(new U(*other.p_)),
deleter_(std::bind(&default_deleter<U>, (U*)p_)) {}
template <typename Y>
explicit pointer(Y* p) : p_(p), deleter_(std::bind(&default_deleter<Y>, p)) {}
~pointer() {
deleter_();
}
T* p_;
std::function<void ()> deleter_;
};
template <typename T>
pointer<T> make_pointer() {
T* p = new T;
return pointer<T>(p, std::bind(&default_deleter<T>, p));
}
int main() {
pointer<Base> b = make_pointer<Derived>();
pointer<Base> b2(new Derived);
return 0;
}
输出为:
Base Ctr Derived Ctr Base Ctr Derived copy Ctr Derived Dtr Base Dtr Derived Dtr Base Dtr
Derived class 的析构函数被调用两次,因为有 2 个指针实例:一个在 make_pointer 函数中创建,第二个在 main 函数中创建。
使用普通函数指针实现的解决方案:
#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;
}
以下代码
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;
}
给我以下输出:
Base Ctr
Derived Ctr
Base Dtr
解决这个问题的方法是使基本析构函数成为虚拟的。
但是,当我使用没有虚拟基析构函数的 boost 智能指针时。我得到了不同的输出。
int main()
{
boost::shared_ptr<Base> b = boost::make_shared<Derived>();
}
输出为
Base Ctr
Derived Ctr
Derived Dtr
Base Dtr
boost shared_ptr 如何在不影响(我假设)Base 和 Derived 类.
的情况下实现这一点
它如何为多级继承扩展它,即基点到 dervderv
其中dervderv继承自derv.
编辑:
大多数答案告诉我 "magic" 发生在 make_shared 中。然而,我对以下代码得到了相同的行为
boost::shared_ptr<Base> ptr(new Derived);
Boost 通过删除函子实现了这一点。默认实现在使用 make_shared
.
delete
简而言之,boost::smart_ptr
包含指向对象的指针、引用计数和一个在析构函数中调用的删除函数,当您调用boost::make_shared<Derived>()
时,它将创建[的默认构造对象=25=] Derived
并且 deleter 将指向 Derived
的析构函数。这应该适用于任何长度的继承链,但在基 class 中具有虚拟析构函数确实是强制性的。
考虑这种技术的下一个简化的简单示例实现:
#include <iostream>
#include <functional>
using namespace std;
struct Base
{
public:
Base()
{
std::cout<<"Base Ctr ";
}
~Base()
{
std::cout<<"Base Dtr ";
}
};
struct Derived : Base
{
Derived()
{
std::cout<<"Derived Ctr ";
}
Derived(const Derived& d)
{
std::cout<<"Derived copy Ctr ";
}
~Derived()
{
std::cout<<"Derived Dtr ";
}
};
template <typename T>
void default_deleter(T* p) {
delete p;
}
template <typename T>
struct pointer {
pointer(T* p, std::function<void ()> d) : p_(p), deleter_(d) {}
template <typename U>
pointer(pointer<U> other) : p_(new U(*other.p_)),
deleter_(std::bind(&default_deleter<U>, (U*)p_)) {}
template <typename Y>
explicit pointer(Y* p) : p_(p), deleter_(std::bind(&default_deleter<Y>, p)) {}
~pointer() {
deleter_();
}
T* p_;
std::function<void ()> deleter_;
};
template <typename T>
pointer<T> make_pointer() {
T* p = new T;
return pointer<T>(p, std::bind(&default_deleter<T>, p));
}
int main() {
pointer<Base> b = make_pointer<Derived>();
pointer<Base> b2(new Derived);
return 0;
}
输出为:
Base Ctr Derived Ctr Base Ctr Derived copy Ctr Derived Dtr Base Dtr Derived Dtr Base Dtr
Derived class 的析构函数被调用两次,因为有 2 个指针实例:一个在 make_pointer 函数中创建,第二个在 main 函数中创建。
使用普通函数指针实现的解决方案:
#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;
}