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

时间:2015-02-28 11:12:43

标签: c++ pointers reference abstract-class unique-ptr

我正在用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)

2 个答案:

答案 0 :(得分:1)

你有趣的设计效果非常好!

在显示示例时使用示例,并使用简单的Base

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

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

与您的设计无关的真正问题

查看错误消息,问题似乎非常不同,与unique_ptr完全无关。我

如果MXIO::MXEventBase,则消息显示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
}