【问题标题】:Trying to manually creating unique_ptr class instances with virtual parts尝试使用虚拟零件手动创建 unique_ptr 类实例
【发布时间】:2019-10-28 10:52:54
【问题描述】:

作为硕士论文,我需要在github上扩展数据库duckdb的功能。

第一步是创建一个固定的内部计划,代表类似“select 42;”的内容。只是在物理层面上。为此,我厌倦了使用duckdb 内部使用的类手动创建这样的计划。

在编译时,我通常会收到如下错误消息:

/home/ubuntu/git/duckdb/src/include/common/helper.hpp: In instantiation of ‘std::unique_ptr<T> duckdb::make_unique(Args&& ...)

 [with T = duckdb::Expression; Args = {duckdb::ExpressionType,
 duckdb::ExpressionClass, duckdb::TypeId}]’:   

 /home/ubuntu/git/duckdb/src/execution/physical_plan_generator.cpp:125:155:
 required from here   

 /home/ubuntu/git/duckdb/src/include/common/helper.hpp:24:23: error:

 invalid new-expression of abstract class type ‘duckdb::Expression’   
 return unique_ptr<T>(new T(std::forward<Args>(args)...));

创作是这样的:

unique_ptr<Expression> ProjectionExpression = make_unique<Expression>(ExpressionType::VALUE_CONSTANT, ExpressionClass::BOUND_CONSTANT, TypeId::INTEGER);

构造函数是

Expression::Expression(ExpressionType type, ExpressionClass expression_class, TypeId return_type)
    : BaseExpression(type, expression_class), return_type(return_type) {
}

基础表达式为

   BaseExpression(ExpressionType type, ExpressionClass expression_class)
        : type(type), expression_class(expression_class) {
    }
    virtual ~BaseExpression() {
    }

如您所见,类表达式使用类 baseExpression 的初始化列表。据我所知,两者之间没有直接继承,但显然我需要当前缺少的东西来正确初始化构造函数。

问题是通常在duckdb中,这些东西来自解析器,然后从这些对象构建。我必须尝试猜测数据结构应该是什么样子。

我在弄清楚如何使用 make_unique 直接分配此对象时遇到问题,因为表达式显然需要某种 baseExpression,但 baseexpression 本身具有虚拟组件,因此我也不能直接创建该组件。

基本上我要问的是:当类是抽象的时,你如何创建一个新的 unique_ptr 对象?

【问题讨论】:

  • 你必须实例化一些派生类,而不是抽象类。无论是使用unique_ptr,还是使用任何其他构造方法,都无法在 C++ 中实例化抽象类。 C++ 不能以这种方式工作。

标签: c++ class unique-ptr duckdb


【解决方案1】:

当类是抽象类时如何创建一个新的 unique_ptr 对象?

通过创建一个具体的非抽象子类的实例,并将其作为指向抽象基类的指针返回。这是使用工厂模式和类似习惯用法时的常见做法。

【讨论】:

    【解决方案2】:

    查看here 的源代码,您会看到Expression 有一个pure virtual member function(可通过virtual 和= 0 识别):

    class Expression : public BaseExpression {
        //...
    
        virtual unique_ptr<Expression> Copy() = 0;
    
        //...
     };
    

    具有纯虚成员函数的类是abstract class。无法创建抽象类的实例(无论是作为具有自动存储持续时间的变量,使用new 还是使用std::make_unique)。相反,您需要选择从Expression 派生的适当类,该类实现所有纯虚拟方法并创建该类的实例,例如致电std::make_unique&lt;DerivedClass&gt;(...)。之后您仍然可以将其分配给std::unique_ptr&lt;Expression&gt;。

    问题一般不是虚成员函数,只是纯虚成员函数。在没有纯虚成员函数的情况下,带有虚函数的类可以毫无问题地与std::make_unique一起使用。

    【讨论】:

      猜你喜欢
      • 2014-10-15
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-15
      • 2013-07-29
      • 1970-01-01
      相关资源
      最近更新 更多