Abstract Class in std::unique_ptr as a Return from Function not Working
Abstract Class in std::unique_ptr as a Return from Function not Working
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{});
}
这段代码只是一个简化版本,它复制了我面临的问题。
我这个设计的目的是在一棵树上创建一个访问者模式,然后把它变成另一棵树。
我已将眼前的问题缩小到 D1Generic
和 D2Generic
函数。我在这里的目的是创建一个可扩展的接口,允许 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.
试试这个:
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();
}
在 中探讨了根本问题,但解决方案的详细信息有所不同。
调用 std::make_unique<T>
动态分配类型 T
的对象。这些参数不会影响创建的内容,只会影响它的初始化方式。当您提供 D1
类型的对象来初始化 Base
类型的 dynamically-allocated 对象时,对 D1
对象的引用将转换为对其 [=14= 的引用] sub-object,新对象是copy-constructed。
您(大概)想要做的是动态分配类型为 D1
的对象,然后将其地址转换为 pointer-to-Base
。即投after构造.
return std::make_unique<D1>();
这会动态分配一个 D1
类型的对象,为新对象创建一个 unique_ptr
。这个智能指针通过移动语义返回。这意味着返回的对象(声明为 unique_ptr<Base>
)是 make_unique
返回的 unique_ptr<D1>
中的 move-constructed。幸运的是,这是允许的!
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{});
}
这段代码只是一个简化版本,它复制了我面临的问题。 我这个设计的目的是在一棵树上创建一个访问者模式,然后把它变成另一棵树。
我已将眼前的问题缩小到 D1Generic
和 D2Generic
函数。我在这里的目的是创建一个可扩展的接口,允许 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.
试试这个:
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();
}
在
调用 std::make_unique<T>
动态分配类型 T
的对象。这些参数不会影响创建的内容,只会影响它的初始化方式。当您提供 D1
类型的对象来初始化 Base
类型的 dynamically-allocated 对象时,对 D1
对象的引用将转换为对其 [=14= 的引用] sub-object,新对象是copy-constructed。
您(大概)想要做的是动态分配类型为 D1
的对象,然后将其地址转换为 pointer-to-Base
。即投after构造.
return std::make_unique<D1>();
这会动态分配一个 D1
类型的对象,为新对象创建一个 unique_ptr
。这个智能指针通过移动语义返回。这意味着返回的对象(声明为 unique_ptr<Base>
)是 make_unique
返回的 unique_ptr<D1>
中的 move-constructed。幸运的是,这是允许的!