返回对通过其接口指向的对象的引用

Returning a reference to an object pointed through its interface

我正在用 C++ 构建一个小型框架,其中包含作为 unique_ptr 接口存储在 STL 容器中的对象。我认为 unique_ptr 是最佳选择,因为容器应该是对象的唯一所有者。

我想从容器中检索指向对象的引用以传递给调用者。但是当我得到指针时,我需要取消引用它以传递来自我的函数的内容引用,这当然不适用于抽象 class。

我不想传递会违背我正在开发的整个概念的原始指针。 我无法转换,因为我不知道存储对象的具体类型。 我想到的唯一合理的解决方案是在容器中存储一个共享指针,并将一个弱指针传递给调用者,但如果你知道其他一些方法来获得相同的结果,那就太好了。

这是一个基本的代码结构,Base是一个抽象class:

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:问题已解决

我解决了这个问题。问题不在于函数 returning 的方式,而在于我捕捉 return 的方式。我正在使用

auto tmp = X.get(10) 

假设 auto 会在我应该使用的时候处理引用

auto&& tmp = X.get(10)

您的有趣设计非常完美!

使用您显示的示例,并使用简单的 Base

  • Container代码编译无误;
  • 调用代码编译也没有任何错误。

因此您的代码段无法重现该错误。并且您的设计按预期工作。

实际问题与你的设计无关

查看错误消息,问题似乎与 unique_ptr 完全不同并且完全不相关。我

如果 MXIO::MXEventBase,消息说 Base 是一个抽象 class。事实上,当向我的简单 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 !! 

请注意,幸运的是您的基础 class 是抽象的,您收到了一条错误消息。使用具体的基础 class 它会编译得很好但对象会是 sliced

如果你不想失去抽象的多态性class你必须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&& 效果不佳,因为返回了引用。

根据 Christophe 的建议,我将 post 我遇到的问题的解决方案作为答案:

问题不在于函数 return 获取结果的方式,而在于我捕获结果的方式。

int main() {
Container X;
// Fill X here
A tmp = X.get(10) // Let's say I want the tenth element
}

正如 Christophe 指出的那样,这段代码的问题在于 tmp 不是对 returned 对象的引用,而是一个具体对象,当然不能将其实例化为基础 class 是抽象的.

在这种情况下,应该通过引用 return 本身来捕获

int main() {
Container X;
// Fill X here
A& tmp = X.get(10) // Let's say I want the tenth element
}