我有一个场景,我使用pass-by-reference获取MyClass的向量,如下所示:
std::vector<shared_ptr<MyClass>>& x = myObj->getVector();
但是当我这样做时:
x.clear();
我期待myObj中的底层向量的大小为零,因为我使用pass-by-reference检索它。然而,这种情况并非如此。这是为什么?
编辑:
返回的向量是数据成员,而不是getVector()
中创建的向量。
EDIT2:这是getVector()
:
std::vector<shared_ptr<MyClass>> myVec;
std::vector<shared_ptr<MyClass>> getVector(){
return myVec;
}
答案 0 :(得分:4)
它只返回对象
然后你的编译器不应该接受这个代码,因为调用getVector
的rvalue结果不能绑定到左值引用x
。 Microsot的编译器因为允许语言扩展以允许这样的行为而臭名昭着,并且许多人都讨厌这种扩展。
我认为该方法的返回类型不是决定PbR / PbV的原因,而是调用代码(我上面发布的部分)是否有“&amp;”?
如果作为参考只是由来电者决定,这会做什么?
myObj->getVector().clear();
相反,函数需要通过引用返回,以便调用者接收对象的引用(使上面的示例工作正常)。
如果决定存储函数的结果,则变量必须是引用,否则结果将被复制或移动到变量中(在返回值为引用的情况下复制)。调用者的变量也允许直接构造成通过RVO,但同样,不是当返回值是参考时。
除非使用引用,否则C ++将传递并按值返回 。默认值是值语义,你可能认为它很糟糕,但是当移动语义开始发挥作用时,最终会更好地工作。
答案 1 :(得分:1)
您可以使用几种方法解决此问题。
更改getVector()
的返回类型以返回对成员数据的引用。
std::vector<shared_ptr<MyClass>>& getVector(){
return myVec;
}
然后,您可以使用
myObj->getVector().clear();
清除myObj->myVec
。
添加成员函数clearVector()
并调用它。
void clearVector(){
myVec.clear();
}
然后,您可以使用
myObj->clearVector();