Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何在3';具有受保护析构函数和公共销毁方法的d party类_C++_Boost_Destructor_Shared Ptr_Protected - Fatal编程技术网

C++ 如何在3';具有受保护析构函数和公共销毁方法的d party类

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,它提供了一种“销毁”方法 直截了当的

我是一个类a的客户机,它的析构函数在protected中定义。此外,我不能更改它的接口(我故意编写了“3'dParty类”,尽管我的意思是,无论出于何种原因,都不允许更改它的接口。 那么,在这种情况下如何使用boost::shared_ptr呢? 析构函数是虚拟的:

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还不够吗?@hellfire769
FooDerivated
是一个派生
Foo
的示例类。但是,如果可以修改派生
Foo
的所有类,则可以使用该解决方案。我想/证明/多态性行为受到尊重(您可以将共享指针设置为派生指针)。此外,别忘了,
FooBase
的唯一目的是将服务器作为“可删除”的中间人。
Destroy
~FooDerived
~FooBase