c++ - std::unique_ptr 中的抽象类作为函数的返回不起作用

标签 c++ polymorphism std subclass unique-ptr

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职能。我的目的是创建一个可扩展的接口(interface),允许 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.

最佳答案

Abstract class and unique pointer 中探讨了根本问题,但解决方案细节不同。
调用 std::make_unique<T>动态分配 T 类型的对象.参数不影响创建的内容,只影响它的初始化方式。当您提供 D1 类型的对象时初始化 Base 类型的动态分配对象,对 D1 的引用对象被强制转换为对其 Base 的引用子对象,并且新对象是从中复制构建的。
你(大概)想要做的是动态分配一个 D1 类型的对象。 ,然后将其地址转换为指向- Base 的指针.即施工后浇筑。

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

关于c++ - std::unique_ptr 中的抽象类作为函数的返回不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63626718/

相关文章:

c++ - MEX 文件如何为 C++ 程序提供参数?

c++ - 使用 boost spirit x3 解析逗号分隔的 0 个或多个列表

java - 这段代码的含义是什么?与多态性相关

java - java中函数重载与跨继承类的函数重写

c++ - 为什么我不能将这个比较函数作为模板参数传递?

c++ - 通过引用返回 std::Vector<> 很慢?

c++ - 在 C++ 中重新设置引用。代码如何编译?

c++ - 如何将已实现的虚拟成员函数作为参数传递

Java - 具有集合属性的多态性

c++ - std 容器在多线程环境中是否总是抛出异常?