返回对通过其接口指向的对象的引用
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::MXEvent
是 Base
,消息说 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
}
我正在用 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::MXEvent
是 Base
,消息说 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
}