【问题标题】:Abstract Class in std::unique_ptr as a Return from Function not Workingstd::unique_ptr 中的抽象类作为函数的返回不起作用
【发布时间】:2020-12-16 23:17:50
【问题描述】:
class Base{
public:
    virtual std::string typeName() = 0;
    virtual ~Base() = 0;
};
Base::~Base(){}

class D1 : public Base{
public:
    std::string typeName();
    std::vector<std::unique_ptr<Base>> children;
    ~D1(){};
};
class D2 : public Base{
public:
    std::string typeName();
    std::unique_ptr<Base> child;
    ~D2(){};
};
std::string D1::typeName(){
    return "class D1";
}
std::string D2::typeName(){
    return "class D2";   
}

class Program{
public:
   std::unique_ptr<Base> D1Generic();
   std::unique_ptr<Base> D2Generic();
};
std::unique_ptr<Base> Program::D1Generic(){
    return std::make_unique<Base>(D1{});
}
std::unique_ptr<Base> Program::D2Generic(){
    return std::make_unique<Base>(D2{});
}

此代码只是一个简化版本,它复制了我所面临的问题。 我对这个设计的意图是在一棵树上创建一个访客模式,然后把它变成另一棵树。

我已将当前问题的范围缩小到 D1GenericD2Generic 函数。我的目的是创建一个可扩展的接口,允许Base 的多个子类以多态方式作为唯一的指针变量。

我收到了这些错误:

/usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/unique_ptr.h:821:34: error: 
      allocating an object of abstract class type 'Base'
    { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
                                 ^
main.cpp:38:17: note: in instantiation of function template specialization
      'std::make_unique<Base, D1>' requested here
    return std::make_unique<Base>(D1{});
                ^
main.cpp:8:25: note: unimplemented pure virtual method 'typeName' in 'Base'
    virtual std::string typeName() = 0;
                        ^
main.cpp:9:13: note: unimplemented pure virtual method '~Base' in 'Base'
    virtual ~Base() = 0;
            ^
In file included from main.cpp:4:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/memory:80:
/usr/bin/../lib/gcc/x86_64-linux-gnu/7.5.0/../../../../include/c++/7.5.0/bits/unique_ptr.h:821:34: error: 
      allocating an object of abstract class type 'Base'
    { return unique_ptr<_Tp>(new _Tp(std::forward<_Args>(__args)...)); }
                                 ^
main.cpp:41:17: note: in instantiation of function template specialization
      'std::make_unique<Base, D2>' requested here
    return std::make_unique<Base>(D2{});
                ^
2 errors generated.

【问题讨论】:

    标签: c++ polymorphism std subclass unique-ptr


    【解决方案1】:

    试试这个:

    std::unique_ptr<Base> Program::D1Generic() {
        return (std::unique_ptr<Base>)new D1();
    }
    std::unique_ptr<Base> Program::D2Generic() {
        return (std::unique_ptr<Base>)new D2();
    }
    

    【讨论】:

      【解决方案2】:

      Abstract class and unique pointer 探讨了根本问题,但解决方案细节不同。

      std::make_unique&lt;T&gt; 的调用会动态分配T 类型的对象。参数不影响创建的内容,只影响它的初始化方式。当您提供D1 类型的对象来初始化Base 类型的动态分配对象时,对D1 对象的引用被转换为对其Base 子对象的引用,并且新对象为从那里复制构建。

      您(大概)想要做的是动态分配D1 类型的对象,然后将其地址转换为指向Base 的指针。也就是说,构造之后强制转换。

      return std::make_unique<D1>();
      

      这会动态分配D1 类型的对象,为新对象创建unique_ptr。这个智能指针是通过移动语义返回的。这意味着返回的对象(声明为unique_ptr&lt;Base&gt;)是从make_unique 返回的unique_ptr&lt;D1&gt; 移动构造的。幸运的是,这是允许的!

      【讨论】:

        猜你喜欢
        • 2021-09-23
        • 2017-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 2018-01-02
        • 2012-09-02
        • 2022-10-21
        相关资源
        最近更新 更多