使用unique_ptr保护的析构函数 [英] protected destructor with unique_ptr

查看:386
本文介绍了使用unique_ptr保护的析构函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图从第三方库调用API。

I am trying to call APIs from a third party library.

当我要对具有受保护析构函数的类使用unique_ptr时遇到麻烦。

There is a trouble when I want to use unique_ptr with a class having protected destructor.

这里是示例,

#include <memory>
#include <iostream>

using namespace std;

class Parent {  
  public:  
    Parent () //Constructor
    {
        cout << "\n Parent constructor called\n" << endl;
    }
  protected:
    ~ Parent() //Dtor
    {
        cout << "\n Parent destructor called\n" << endl;
    }
};

class Child : public Parent 
{
  public:
    Child () //Ctor
    {
        cout << "\nChild constructor called\n" << endl;
    }
    ~Child() //dtor
    {
        cout << "\nChild destructor called\n" << endl;
    }
};

Parent* get() {
  return new Child();
}

int main(int argc, char const* argv[])
{
  Parent * p1 = get(); // this is ok
  std::unique_ptr<Parent> p2(get()); // this is not ok
  return 0;
}

我正在尝试将Parent_ptr与Parent类一起使用。但是编译器抛出了错误

I am trying to use unique_ptr with Parent class. But the compiler threw the errors

/usr/include/c++/5/bits/unique_ptr.h: In instantiation 
of ‘void std::default_delete<_Tp>::operator()(_Tp*) const 
[with _Tp = Parent]’:
/usr/include/c++/5/bits/unique_ptr.h:236:17:   required 
from ‘std::unique_ptr<_Tp, _Dp>::~unique_ptr() [with _Tp 
= Parent; _Dp = std::default_delete<Parent>]’
main.cpp:38:35:   required from here
main.cpp:12:5: error: ‘Parent::~Parent()’ is protected
 ~ Parent() //Dtor
 ^
In file included from /usr/include/c++/5/memory:81:0,
             from main.cpp:2:
/usr/include/c++/5/bits/unique_ptr.h:76:2: error: within 
this context
  delete __ptr;

是否有摆脱此问题的想法?我不能破解Parent和Child类,因为它们是第三方库的类。

Any idea about getting rid of this issue? I can't hack Parent and Child class since they are the classes of the third party library.

推荐答案

您可以使 std :: default_delete< Parent> Parent 的朋友来修复该错误。而且,您可能还想使〜Parent 虚拟避免删除时的不确定行为通过 Parent 指针创建派生类。

You can make std::default_delete<Parent> a friend of Parent to fix that error. And you may also like to make ~Parent virtual to avoid undefined behaviour when deleteing a derived class through Parent pointer.

例如:

class Parent { 
    friend class std::default_delete<Parent>;
    // ...
protected:
    virtual ~Parent();
    // ...






但是, Parent 设计清楚地表明,您不应该通过 Parent 删除 c $ c>指针,这就是为什么析构函数是非公共的。阅读虚拟化了解更多详细信息:


However, Parent design makes it clear that you are not supposed to delete through Parent pointer, this is why the destructor is non-public. Read Virtuality for more details:


准则4:基类析构函数应该是公共的和虚拟的,或者是受保护的且非虚拟的。

Guideline #4: A base class destructor should be either public and virtual, or protected and nonvirtual.






您可能想引入另一个中间基类来解决此问题:


You may like to introduce another intermediate base class to solve the issue:

class Parent { // Comes from a 3rd-party library header.
protected:
    ~Parent();
};

struct MyParent : Parent {  // The intermediate base class.
    virtual ~MyParent();
};

class Derived : public MyParent {};

std::unique_ptr<MyParent> createDerived() {
    return std::unique_ptr<MyParent>(new Derived);
}

int main() {
    auto p = createDerived();
}

这篇关于使用unique_ptr保护的析构函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆