私有对象指针vs对象值,以及返回对象内部

Gli*_*itz 1 c++ encapsulation pointers

相关:C++私有指针"泄漏"?

根据Effective C++(第28项),"避免将句柄(引用,指针或迭代器)返回到对象内部.它增加了封装,帮助const成员函数执行const,并最小化悬空句柄的创建."

按值返回对象是我能想到避免返回句柄的唯一方法.这对我来说建议我应尽可能多地返回私有对象内部.

但是,要按值返回对象,这需要复制构造函数,这违反了"DISALLOW_COPY_AND_ASSIGN"运算符的Google C++样式指南.

作为一个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); 
Run Code Online (Sandbox Code Playgroud)

如果客户端使用以下代码创建函数:

GUIObject *pgo; // point to some GUIObject
const Point *pUpperLeft = &(boundingBox(*pgo).upperLeft());
Run Code Online (Sandbox Code Playgroud)

"对boundingBox的调用将返回一个新的,临时的Rectangle对象[(在这里称为temp.)]然后将在temp上调用upperLeft,并且该调用将返回对temp的内部部分的引用,特别是对其中一个构成它的点...在语句结束时,boundingBox的返回值temp将被销毁,这将间接导致temp点的破坏.反过来,这将使pUpperLeft指向不再是一个对象存在".Meyers,Effective C++(Item 28)

我认为他建议按值返回Point以避免这种情况:

const Point upperLeft() const { return pData->ulhc; }
Run Code Online (Sandbox Code Playgroud)

Tim*_*sch 5

我们说,谷歌C++风格指南有点"特殊",并引发了对各种C++新闻组的大量讨论.让我们离开吧.

在正常情况下,我建议遵循Effective C++中的指南通常被认为是一件好事; 在您的特定情况下,返回一个对象而不是对内部对象的任何类型的引用通常是正确的做法.大多数编译器都非常擅长处理大的返回值(谷歌的返回值优化,几乎每个编译器都这样做).

如果使用分析器进行测量表明返回值正在成为瓶颈,那么我会考虑其他方法.