C++ 如何在3';具有受保护析构函数和公共销毁方法的d party类
我是一个类a的客户机,它的析构函数在protected中定义。此外,我不能更改它的接口(我故意编写了“3'dParty类”,尽管我的意思是,无论出于何种原因,都不允许更改它的接口。 那么,在这种情况下如何使用boost::shared_ptr呢? 析构函数是虚拟的:C++ 如何在3';具有受保护析构函数和公共销毁方法的d party类,c++,boost,destructor,shared-ptr,protected,C++,Boost,Destructor,Shared Ptr,Protected,我是一个类a的客户机,它的析构函数在protected中定义。此外,我不能更改它的接口(我故意编写了“3'dParty类”,尽管我的意思是,无论出于何种原因,都不允许更改它的接口。 那么,在这种情况下如何使用boost::shared_ptr呢? 析构函数是虚拟的: Class Foo { public: void Destroy () {} protected: virtual ~Foo () {} } 对于Foo,它提供了一种“销毁”方法 直截了当的
Class Foo {
public:
void Destroy () {}
protected:
virtual ~Foo () {}
}
对于Foo,它提供了一种“销毁”方法
直截了当的用法
无法编译以下代码:
boost::shared_ptr <Foo> a = boost::make_shared <Foo> ();
boost::shared_ptr a=boost::make_shared();
编译器消息:
...
错误…“Foo::~Foo()不可访问
另外,我的工作场所的编译器不支持c++11简单
boost::shared_ptr<Foo> ptr(new Foo(), [](Foo *p){ p->Destroy(); });
boost::shared_ptr ptr(新的Foo(),[](Foo*p){p->Destroy();});
回复结论:这是图书馆设计模式不好的问题(抽象类的析构函数应该是
public
)。因此,您不能在此库中使用shared_ptr
,或者您应该将析构函数更改为public
,以便通过编辑库的头文件来使用shared_ptr
,即使它非常糟糕您可以创建一个中间类作为助手多态库:
仅使用c++03的示例:
#include <boost/shared_ptr.hpp>
#include <iostream>
class Foo { // "abstract"
public:
virtual void Destroy () { std::cout << __FUNCTION__ << "\n"; }
protected:
virtual ~Foo () {}
};
class FooBase : public Foo {
public:
static void Deleter(FooBase* p) {
if (p)
p->Destroy();
delete p;
}
// protected:
virtual ~FooBase() { std::cout << __FUNCTION__ << "\n"; }
};
class FooDerived : public FooBase
{
~FooDerived() { std::cout << __FUNCTION__ << "\n"; }
};
int main()
{
boost::shared_ptr<FooBase> p(new FooDerived, FooBase::Deleter);
}
注意析构函数如何实际上受到
保护
现在。这可以确保所有的析构函数都经过FooBase::Deleter
析构函数是虚拟的吗?是的,忘了提及……你在尝试做什么,因为你提供的信息并不表明你有任何错误h执行std::shared_ptr。在没有任何自定义删除程序的情况下使用直接共享_ptr会生成编译器错误。boost::shared_ptr默认删除程序调用~ACustom deleter不必调用析构函数,只要Destroy函数调用它。注意,他使用的是boost::shared_ptr。删除程序是否也需要在p
上调用delete
n boost-原始指针是否会被释放(当引用计数为0时)?抱歉,@ikh这是非常糟糕的建议(更改标头)。它违反了ODR。它不违反标准,只是不可靠。类布局甚至可能会更改。所以不要更改。另外,delete nullptr;
也可以。否problem@ikh你完全没有抓住要点。你不需要更改它。如果析构函数是私有的,你无论如何都不能对它调用delete
,无论是使用还是使用退出智能指针。它可能不打算手动删除。在OP的情况下,可能直接派生出Foo
派生出Foo
。如果不是,这是一个很好的解决方案!已修复。现在不再使用boost::bind
。请注意,如果您愿意(/cc@ikh),析构函数现在可以很好且私有@为什么定义FooDerivated?FooBase还不够吗?@hellfire769FooDerivated
是一个派生Foo
的示例类。但是,如果可以修改派生Foo
的所有类,则可以使用该解决方案。我想/证明/多态性行为受到尊重(您可以将共享指针设置为派生指针)。此外,别忘了,FooBase
的唯一目的是将服务器作为“可删除”的中间人。
Destroy
~FooDerived
~FooBase