我正在用 C++ 构建一个小型框架,其中包含作为其接口(interface)的 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
}
在 OSX 上使用 clang 进行编译时出现此错误
variable type 'MXIO::MXEvent' is an abstract class
编辑2:问题已解决
我解决了这个问题。问题不在于函数返回的方式,而在于我捕获返回的方式。我正在使用
auto tmp = X.get(10)
假设 auto 会在我应该使用的时候负责获取引用
auto&& tmp = X.get(10)
最佳答案
您有趣的设计效果非常好!
使用您显示的示例,并使用简单的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&&
却不行,因为返回了引用。
关于c++ - 返回对通过其接口(interface)指向的对象的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28781032/