相关:C++ private pointer "leaking"?私有对象指针VS对象值,并返回对象内部构件
根据有效的C++(项目28),“避免返回手柄(引用,指针,或迭代器)到对象内部它增加封装。 ,可以帮助const成员函数执行const,并最大限度地减少悬挂句柄的创建。“
通过值返回对象是我能想到的避免返回句柄的唯一方法。对我来说这意味着我应该尽可能地按照值返回私有对象内部。
但是,要按值返回对象,这需要使用与“DISALLOW_COPY_AND_ASSIGN”运算符的相反的拷贝构造函数。作为一个C++新手,除非我错过了一些东西,否则我会发现这两个建议互相冲突。
所以我的问题是:是否没有银弹,允许有效的引用返回对象内部不容易晃动指针? const引用返回的效果如何?另外,我应该而不是经常使用私人对象字段的指针吗?根据价值或指针选择何时存储对象的私有实例字段的一般规则是什么?
(编辑)为了清楚起见,迈尔斯例如悬空指针代码:
class Rectangle {
public:
const Point& upperLeft() const { return pData->ulhc; }
const Point& lowerRight() const { return pData->lrhc; }
...
};
class GUIObject { ... };
const Rectangle boundingBox(const GUIObject& obj);
如果客户端创建具有这样的代码的函数:
GUIObject *pgo; // point to some GUIObject
const Point *pUpperLeft = &(boundingBox(*pgo).upperLeft());
“到boundingBox的呼叫将返回一个新的,临时的Rectangle对象[(这里称为temp)。]然后upperLeft将在temp上被调用,并且该调用将返回对temp内部部分的引用,特别是对其中一个点的引用。 ..在结束的时候表达式,boundingBox的返回值temp会被销毁,并且会间接导致temp的Points被破坏。这反过来,将离开pUpperLeft指向不再存在的对象“迈尔斯,有效的C++(第28项)
我觉得他是在暗示将要返回的值点来避免这一点:
const Point upperLeft() const { return pData->ulhc; }
哦,我不得不同意迈尔斯那么。仅仅因为客户端可能会误用这些函数并由于销毁Rectangle而导致引用无效,而不是按值返回所有内容的理由,所以通过const引用而不是按值返回Point。客户应该足够了解他需要一个被返回的点的副本(在这种情况下,当你通过const引用返回时,他仍然可以这样做)。我最喜欢迈尔斯,但这本书像12岁。 Sutter在这种情况下会与他矛盾,并建议Point应该通过const参考返回 – stinky472 2010-06-27 12:57:52
以避免'pessimization'[...]。尽管如此,如果这就像一个窗口句柄被返回到控件,你通常希望避免返回它,因为它会放弃你的类保持不变量的能力。 – stinky472 2010-06-27 12:58:37