您的位置:首页 > 编程语言 > C语言/C++

C++实现之——尽量避免返回handles指向对象内部成分

2013-06-03 16:56 141 查看
定义下面的类和结构:

class Point
{
public:
Point(int x, int y);
...
void setX(int newVal);
void setY(int newVal);
};
struct RectData
{
Point ulhc;
Point lrhc;
};
class Rectangle
{
...
private:
std::tr1::shared_ptr<RectData> pData;
};


那么下面的成员变量是否有不合理的地方:

class Rectange
{
public:
Point& upperLeft() { return pData->ulhc; }
Point& lowerRight() { return pData->lrhc; }
...
};


上面不合理的地方在第4和第5行,const成员变量的本意是只返回数据,但不允许修改对象内部的数据,但是上面的代码由于返回了指向对象内部变量的handle,破坏了封装性,因为用户可以通过这个handle来修改Point的属性。为了解决这个问题,可以令这个handle为const,这样就不可修改,即:

const Point& upperLeft() { return pData->ulhc; }
const Point& lowerRight() { return pData->lrhc; }


即使如此,返回指向对象内部的handle还可能带来其他的问题,比如返回一个空的handle,例如下面的代码:

class GUIObject { ... };
const Rectangle boundingBox(const GUIObject& obj);

GUIObject* pgo;
...
const Point* pUpperLeft = &(boundingBox(*pgo).upperLeft));


第6行Point指向boundingBox(*pgo)获得的一个临时对象的一个内部成员,但是由于boundingBox(*pgo)返回对象在语句6执行结束后就会被析构,从而导致其内部成员变量Point对象也会被析构,因而pUpperLeft将指向一个空的对象,即变成空悬、虚吊即dangling的handle。

当然,并不是所有的成员函数都不该返回handle,例如operator[],它需要返回指向容器内部数据的handle。

综上,在定义类的过程中,应避免返回handle指向对象内部成分,这样可以增加封装性,使得const成员函数执行起来真正具有const的性质,并避免得到虚吊的handle。

以上整理自Effective C++中文版第三版case 28.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: