cppyy 继承包含智能指针的类

Posted

技术标签:

【中文标题】cppyy 继承包含智能指针的类【英文标题】:cppyy inherit class that contains a smart pointer 【发布时间】:2020-05-13 00:15:03 【问题描述】:

这是一个从包含智能指针的类继承的简单示例。我们不做任何事情,只是声明它。

import cppyy

cppyy.cppdef("""
  class Example  
   private:
    std::unique_ptr<double> x;
   public:
    Example() 
    virtual ~Example() = default;
    double y = 66.;
   ;
  """)

class Inherit(cppyy.gbl.Example):
    pass

 a = Inherit()
 print(a.y)  # Test whether this attribute was inherited

示例运行,但智能指针出错

input_line_19:9:43: error: call to implicitly-deleted copy constructor of '::Example'
  Dispatcher1(const Dispatcher1& other) : Example(other), m_self(other.m_self, this) 
                                          ^       ~~~~~
input_line_17:4:29: note: copy constructor of 'Example' is implicitly deleted because field 'x' has a deleted copy constructor
    std::unique_ptr<double> x;
                            ^
/usr/include/c++/7/bits/unique_ptr.h:383:7: note: 'unique_ptr' has been explicitly marked deleted here
      unique_ptr(const unique_ptr&) = delete;
      ^
smart_ptr.py:14: RuntimeWarning: no python-side overrides supported
  class Inherit(cppyy.gbl.Example):
66.0

尽管如此,继承似乎仍然有效,因为我们仍然可以从 C++ 类访问公共变量。实际上,我不是 100% 确定 cppyy 是否有错。虽然 C++ 看起来不错,但我可能以一种奇怪的方式使用智能指针/虚拟析构函数,因为我对智能指针没有那么丰富的经验。

如果我使用 std::shared_ptr 而不是 std::unique_ptr,则不会引发错误

【问题讨论】:

为 Example 定义自定义复制构造函数。 @S.M.啊,知道了,如果我尝试从 Example 类继承,C++ 中会出现这个问题吗?或者实际上是一个 cppyy 怪癖? 上游的问题:由于dispatcher添加了一个数据成员(要调度到的Python对象),cppyy需要自定义复制构造函数,如果有的话。它从上游收集所有构造函数,即使它不应该为它提供复制构造函数声明,所以 cppyy “看到” 复制构造函数并提供自定义实现。然后 JIT 失败。 提交了错误报告:bitbucket.org/wlav/cppyy/issues/234/… 【参考方案1】:

正如 S.M. 所暗示的,如果我们必须使用 unique_ptr,技巧似乎是确保定义一个复制构造函数,例如,这个例子给出了预期的结果,没有错误消息,

import cppyy

cppyy.cppdef("""
  class Example  
    std::unique_ptr<double> x;
   public:
    Example()  x = std::unique_ptr<double>(new double(123.));  
    // Copy constructor
    Example(const Example& other) : x(other.x ? nullptr : new double(*other.x)) 
    virtual ~Example() = default;
    double y = 66.;
    double get_x()  return *x; 
  ;
  auto e = Example();
  auto f = e;
  """)

class Inherit(cppyy.gbl.Example):
  pass

a = Inherit()
print(a.get_x())  # prints 123.
print(a.y)  # prints 66.

【讨论】:

我会在取消引用之前检查x,如Example(const Example&amp; other) : x(other.x ? nullptr : new double(*other.x))

以上是关于cppyy 继承包含智能指针的类的主要内容,如果未能解决你的问题,请参考以下文章

如何使用智能指针跟踪类的对象?

使用智能指针进行继承的 pimpl

c++11智能指针(一) shared_ptr

C++智能指针类模板

在具有智能指针的类上正确实现复制构造函数和等于运算符

C++ 中带智能指针的依赖注入