Related to: http://stackoverflow.com/questions/2625719/c-private-pointer-leaking
According to Effective C++ (Item 28), "avoid returning handles (references, pointers, or iterators) to object internals. It increases encapsulation, helps const member functions act const, and minimizes the creation of dangling handles."
Returning objects by value is the only way I can think of to avoid returning handles. This to me suggests I should return private object internals by value as much as possible.
However, to return object by value, this requires the copy constructor which goes against the Google C++ Style Guide of "DISALLOW_COPY_AND_ASSIGN" operators.
As a C++ newbie, unless I am missing something, I find these two suggestions to conflict each other.
So my questions are: is there no silver bullet which allows efficient reference returns to object internals that aren't susceptible to dangling pointers? Is the const reference return as good as it gets? In addition, should I not be using pointers for private object fields that often? What is a general rule of thumb for choosing when to store private instance fields of objects as by value or by pointer?
(Edit) For clarification, Meyers' example dangling pointer code:
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);
If the client creates a function with code such as:
GUIObject *pgo; // point to some GUIObject
const Point *pUpperLeft = &(boundingBox(*pgo).upperLeft());
"The call to boundingBox will return a new, temporary Rectangle object [(called temp from here.)] upperLeft will then be called on temp, and that call will return a reference to an internal part of temp, in particular, to one of the Points making it up...at the end of the statement, boundingBox's return value temp will be destroyed, and that will indirectly lead to the destruction of temp's Points. That, in turn, will leave pUpperLeft pointing to an object that no longer exists." Meyers, Effective C++ (Item 28)
I think he is suggesting to return Point by value instead to avoid this:
const Point upperLeft() const { return pData->ulhc; }