我正在用C ++构建一个小框架,它包含作为unique_ptr
存储在STL容器中的对象到它们的接口。我认为unique_ptr
是最好的选择,因为容器应该是对象的唯一所有者。
我想从容器中检索对尖头对象的引用以传递给调用者。但是当我得到指针时,我需要取消引用它以传递来自我的函数的内容的引用,这当然不适用于抽象类。
我不想传递原始指针,它会违反我正在开发的整个概念。 我无法投射,因为我无法知道存储对象的具体类型。 我想到的唯一合理的解决方案就是在容器中存储一个共享指针,并将一个弱指针传递给调用者,但如果你知道其他一些方法来获得相同的结果,那就太棒了。
这是一个基本的代码结构,Base
是一个抽象类:
class Container
{
vector<unique_ptr<Base>> m_C;
public:
Base& GetBase(int index)
{
return *(m_C.at(index)); //This do not compile as Base is abstract
}
};
修改:
我不确定你还需要什么作为例子。主要看起来像这样
int main() {
Container X;
// Fill X here
A tmp = X.get(10) // Let's say I want the tenth element
}
使用clang在OSX上编译我收到此错误
variable type 'MXIO::MXEvent' is an abstract class
EDIT2:问题已解决
我解决了这个问题。问题不在于函数返回的方式,而在于我捕获返回的方式。我正在使用
auto tmp = X.get(10)
假设在我应该使用
时,auto会负责参考auto&& tmp = X.get(10)
答案 0 :(得分:1)
你有趣的设计效果非常好!
在显示示例时使用示例,并使用简单的Base
:
Container
代码没有任何错误; 因此,您的代码段无法重现该错误。并且您的设计按预期工作。
与您的设计无关的真正问题
查看错误消息,问题似乎非常不同,与unique_ptr
完全无关。我
如果MXIO::MXEvent
为Base
,则消息显示Base
是一个抽象类。实际上,在向我的简单Base
添加纯虚函数时,我设法重现了您的错误消息:
Base tmp = X.get(10); // tmp should be a full tmp object copy constructed from returned value
// But we CANNOT instantiate an abstract object !!
请注意,幸运的是您的基类是抽象的,并且您收到了错误消息。使用具体的基类,它编译得很好,但对象应该是sliced!
如果您不想放弃抽象类的多态性,则必须将tmp
作为参考:
Base &c = test.GetBase(4); // here the reference is copied and no new object is instantiated.
// c still reffers to the original concrete derived object.
请注意,虽然auto&&
效果很好,但Base&&
没有,因为会返回引用。
答案 1 :(得分:0)
正如Christophe所建议的那样,我将发布解决问题的方法作为答案:
问题不在于函数返回结果的方式,而在于我捕获结果的方式。
int main() {
Container X;
// Fill X here
A tmp = X.get(10) // Let's say I want the tenth element
}
正如Christophe所指出的,这段代码的问题是tmp不是对返回对象的引用,而是一个具体的对象,当然不能实例化为基类是抽象的。
在这种情况下,应该通过引用
来捕获返回int main() {
Container X;
// Fill X here
A& tmp = X.get(10) // Let's say I want the tenth element
}