条款28:避免返回 handles 指向对象的内部成分(Avoid returning “handles“ to object internals)

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

1.1 提出问题

创建一个矩形的类(Rectangle),为保持Rectangle对象较小,可以只在其对象中保存一个指针,用于指向辅助的结构体,定义其范围的点数据存放在辅助的结构体中:

cpp 复制代码
class Point { // 表示点的类
public:
    Point(int x, int y);
    ...
    void setX(int newVal);
    void setY(int newVal);
    ...
};
struct RectData { // 矩形的点数据
    Point ulhc; // ulhc = " upper left-hand corner"
    Point lrhc; // lrhc = " lower right-hand corner"
};
class Rectangle {
    ...
    //这个设计可以编译,但它是错误的。
    Point& upperLeft() const { return pData->ulhc; }
    Point& lowerRight() const { return pData->lrhc; }
private:
    std::shared_ptr<RectData> pData; 
}; 

Point coord1(0, 0);
Point coord2(100, 100);
const Rectangle rec(coord1, coord2); // Rec是一个const矩形,范围从
					//(0,0)到(100,100)
rec.upperLeft().setX(50); // 现在变为 (50, 0) 到 (100, 100)!

1.2 解决办法

我们可以为函数的返回类型添加const限制来解决这个问题:

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

1.3 其他问题

即便如此,upperLeft和lowerRight仍然会返回对象内部的句柄,这在其他方面可能会造成问题。特别是,它可能导致悬空(dangling )句柄:指向不再存在的对象的句柄。

cpp 复制代码
class GUIObject { ... };
const Rectangle boundingBox(const GUIObject& obj) //返回值为值传递
{
    Rectangle rect;
    //....
    return rect;
}
GUIObject* pgo; 
... // 让pgo指向某个GUIObject
//调用boundingBox将返回一个新的临时矩形对象。
const Point* pUpperLeft = &(boundingBox(*pgo).upperLeft()); 

1.4 总结

避免返回指向对象内部的句柄(引用、指针或迭代器)。遵守这个原则将会增加封装性,帮助const成员函数保持const行为,并可以尽量避免发生悬空句柄的创建。

相关推荐
qq_199886871 小时前
第6板块·第4节:构建系统与多文件项目
c++·人工智能·gpu算力
2601_966949651 小时前
只拿到股票代码还不够:量化程序到底还需要哪些标的信息?——从数据建模开始理解股票元数据
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
m0_734571761 小时前
深入理解5g <十八>传输块tbsize的计算
开发语言·5g
汉克老师2 小时前
GESP2026年9月认证C++三级( 第三部分编程题(2、分割字符串))精讲
c++·gesp·小学生·学c++编程
估值探索者2 小时前
【Python量化系统工程化 #08】关了 SSH 就停?systemd 让脚本开机自启 + 异常自动拉起
java·c++·人工智能·分类·数据挖掘
RAN11426760083 小时前
1.3第一个程序的介绍
开发语言·qt
天若有情6733 小时前
C++花式魔改!手写头文件复刻Java语法,彻底打破编码思维定式
java·c++·语言做语言·jac++
qq_199886873 小时前
第7板块·第3节:CUTLASS 的 GEMM 实现与优化策略
c++·人工智能·gpu算力·cuda
hetao17338373 小时前
2026-09-17 hetao1733837 的刷题记录
c++·算法
blue_ice .3 小时前
Verilog DDS 数字信号发生器:DAC 输出模拟波形与 ADC 回采观测
开发语言·单片机·嵌入式硬件·fpga开发