如何将std :: unique_ptr <parent>与只具有受保护虚拟析构函数的readonly Parent类一起使用

时间:2018-04-13 08:47:08

标签: c++ virtual destructor unique-ptr protected

test.cpp,最小测试代码

#include <memory>
class Parent{ // A Interface That I can't modify! can't add 'friend' or modify 'protected'
protected:
    virtual ~Parent(){};
public:
    // other interfaces that no one is suitable for 'delete this'
};

class Derived : public Parent{ // My class
public:
    virtual ~Derived(){}
};

class Deleter : public Parent // My deleter to use unique_ptr
{
public:
    void operator()(Parent* ptr)
    {
        delete ptr; // Actually Wrong, cannot access ptr's protected & private member
    }
};

int main(int argc, char* argv[])
{
    Deleter deleter;
    // use of std::unique_ptr<Parent> error because of delete, so define my deleter to handle delete event.
    std::unique_ptr<Parent, Deleter>(dynamic_cast<Parent*>(new Derived()), deleter);
    return 0;
}

如上面的代码。

有一个只读接口类'Parent',带有受保护的虚析构函数。

unique_ptr<Parent>shared_ptr<Parent>将用于管理从Parent派生的类的对象。

但由于删除操作,直接使用unique_ptr<Parent>( new Derived())导致编译错误。

限制不要编辑Parent类的定义。我尝试创建一个能删除指向Parent的指针的删除器。

经过一些测试,我在Derived类的方法中找到了Parent对象的受保护的&amp;私人会员无法访问。

我很好奇是否有一些解决方案,使用unique_ptr<Parent>而不修改Parent类的定义。

感谢您的帮助。

2 个答案:

答案 0 :(得分:6)

您的班级层次结构格式错误。基类的受保护的析构函数是设计的,以防止您尝试执行的操作。

制作析构函数而不是公开的原因通常是强制执行单例模式,或其他一些原因来排除破坏。多态基类对受保护的析构函数几乎没有理由。

答案 1 :(得分:0)

你可以这样做:

class DerivedDeleter
{
public:
    void operator()(Parent* ptr) const
    {
        delete dynamic_cast<Derived*>(ptr);
    }
};

但问题是将unique_ptr重置为不是Derived的Parent。