C++之避免返回handles指向对象内部成分(28)---《Effective C++》

3 篇文章 0 订阅
1 篇文章 0 订阅

条款28:避免返回handles指向对象内部成分

在讨论今天这个条款之前,我们先来看看如下代码:

class Point{
public:
    Point(int x,int y);
    ...
    void setX(int newVal);
    void setY(int newVal);
    ...
};
struct RectDate{
    Point rlhc;
    Point lrhc;
};
class Rectangle{
public:
    ...
    Point& upperLeft() const
    {
        return pData->ulhc;
    }
    Point& lowerRight() const
    {
        return Data->lrhc;
    };
    ...
private:
    std::trl::shared_ptr<RectData> pData;
};

这样的函数编译没有任何问题,但是逻辑上确实不对!我们可以看一下upperLeft和lowerRight函数被声明为const成员函数,因为它们的目的只是为了提供客户一个得知Rectangle相关坐标点的方法,而不是让客户修改Rectangle,但是另外一个方面,返回的是references指向的是Rectangle内部的private数据,但Rectangle内部的private数据却可以调用自身内部的public函数,导致
调用者可以获取这些references进而改变内部数据!导致不安全性出现啦!
那么我们怎样可以解决这个问题呢?
看看书中的解决办法吧!

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

有了这样的改变,客户就可以取得举行的Points,但不能修改它们吧!

PS:引用(References)、指针和迭代器统统都是所谓的handles(号码牌,用于取得某个对象),而返回一个“代表对象内部数据”的handle,随之而来的是“降低对象封装性”的风险;同时也可以导致像上面所提到的虚假const信息。

有时候,返回handles有可能在其他场合带来问题,更明确的说,可能导致dangling handles(空悬的号码牌),具体见如下代码:

class GUIObject{...};
const Rectangle boundingBox(const GUIObject& obj);
GUIObject* pgo;
...
const Point* pUpperLeft=&(boundingBox(*pgo).upper());

对boundingBox的调用获得一个新的、暂时的Rectangle对象,这个对象那个没有名称,我们称之为temp,然后让upperLeft函数作用于temp身上,返回一个指向temp的内部成分的引用,于是pUpperLeft指向那个对象,当upperLeft()函数结束之后,temp将被销毁,于是temp内的Points析构,进而pUpperLeft指向一个不复存在的对象那个,此时pUpperLeft变成悬吊的对象!

总结:避免返回handles(引用,指针、迭代器)指向对象内部,可以保证类的封装性,并将可能发生“dangling handles”的可能性降至最低!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值