【Effection C++】读书笔记 条款28:避免返回handles指向对象内部成分
【Effective C++】读书笔记 Part5 实现
条款28:避免返回handles指向对象内部成分
避免返回handles(包括references,指针,迭代器)指向对象内部。遵守这个条款可以增加封装性,帮助const成员函数的行为更像要一个const,并将发生diangling handles的可能性降至最低。
对于一个const成员函数,如果其返回reference指向对象本身,那么客户就可以通过调用这个成员函数获得的reference修改对象。这也违背了const成员函数的初衷,虽然其并没有修改相应的对象。
示例如下:
class Point
{
public:Point(int x,int y);void SetX(int val);void SetY(int val);
};//一个矩形需要有的元素,左上角和右下角
struct RectData
{ Point ulhc; Point lrhc;
}; //矩形的定义
class Rectangle
{
public: ... Point& upperLeft() const { return pData->ulhc; }Point& lowerRight() const { return pData->lrhc; }private: std::shared_ptr<RectData> pData; ...
};
对于upperLeft()和lowerRight()其均为const成员函数,但是其返回了reference指向自身对象,所以可以通过如下方式来修改对象的值
Point coord1(0,0);
Point coord2(100,100);
const Rectangle rec(coord1, coord2);
rec.upperLeft().setX(50);//现在rec变成从(50,0)到(100,100)
这里有两个需要注意点:
- 成员变量的封装性最多只等与“返回其reference”的函数的访问级别。
- 如果const成员函数传出一个reference指向自身对象,那么函数的调用者可以通过这个引用来修改对象。
如果将上述函数改为返回 const的reference。
如下:
//矩形的定义
class Rectangle
{
public: ... const Point& upperLeft() const { return pData->ulhc; }const Point& lowerRight() const { return pData->lrhc; }private: std::shared_ptr<RectData> pData; ...
};
确实可以解决通过函数调用而导致对象改变的状态。
但是却又可能导致新的问题,因为返回的reference可能会指向一个已经不存在的对象!
考虑如下代码:
//某函数以by-value形式返回Rectangleconst Rectangle CreateRectangle();const Point * p = &(CreateRectangle().upperLeft());
注意CreateRectangle返回的是一个Rectangle类型的临时变量,在语句结束之后,将会被自动销毁,所以对应的p指针显然是指向一个以及不存在的Rectangle对象中的Point。
综上,就有了返回一个handle代表对象内部成分总是危险的。
【Effection C++】读书笔记 条款28:避免返回handles指向对象内部成分相关推荐
- vb 根据pid获取句柄_C++中避免返回指向对象内部的句柄(handles)
点蓝色字关注"CurryCoder的程序人生" 微信公众号:CurryCoder的程序人生 欢迎关注我,一起学习,一起进步! 1.问题的引入 假如你正在给一个应用写一个矩形类,这个 ...
- 【Effection C++】读书笔记 条款01~条款04
[Effection C++]读书笔记 Part1 让自己习惯C++ 条款01:视C++为一个语言联邦 将C++视为一个由相关语言组成的联邦.在其某个次语言中,各种守则简单易懂,容易记住.但当从一个次 ...
- 【Effection C++】读书笔记 条款10~条款12
[Effection C++]读书笔记 Part2 构造/析构/赋值运算 条款09:绝不在构造和析构函数中调用virtual函数 构造函数和析构函数期间不要调用virtual函数,虽然语法上并不会有错 ...
- 【Effection C++】读书笔记 条款41~条款42
[Effection C++]读书笔记 Part7 模板与泛型编程 条款41:了解隐式接口和编译器多态 本条款主要是讲述了两个概念,隐式接口和编译器多态 1. 显示接口和隐式接口 显示接口是由函数的签 ...
- 【Effection C++】读书笔记 条款05~条款06
[Effection C++]读书笔记 Part2 构造/析构/赋值运算 条款05:了解C++默认编写并调用哪些函数 编译器可以暗自为class创建default构造函数,copy构造函数,copy ...
- 【Effection C++】读书笔记 条款07~条款08
[Effection C++]读书笔记 Part2 构造/析构/赋值运算 条款07:为多态基类声明virtual析构函数 带有多态(polymorphic)性质的base classes应该声明一个v ...
- 【Effection C++】读书笔记 条款20~条款23
[Effective C++]Part4 设计与声明 条款20:宁以pass-by-reference-to-const替换pass-by-value 尽量以pass-by-reference-to- ...
- 【Effection C++】读书笔记 条款29~条款30
[Effective C++]读书笔记 Part5 实现 条款29:为异常安全而努力是值得的 当异常被抛出时,待哟异常安全性的函数会: 不泄漏任何资源. 不允许数据败坏. 异常安全函数提供以下三个保证 ...
- 【Effection C++】读书笔记 条款27:尽量少做转型动作
[Effective C++]读书笔记 Part5 实现 条款27:尽量少做转型动作 C++中的类型转换语法 类型转换语法主要有三种不同的形式: (T)expression //将expression ...
最新文章
- Go 学习笔记(22)— 并发(01)[进程、线程、协程、并发和并行、goroutine 启动、goroutine 特点,runtime 包函数]
- 腾讯云发布全链路数据开发平台WeData,企业数据开发门槛降低60%
- Nginx配置https,反向代理多实例tomcat的操作记录
- android url webview,android - webview获取到当前页面的url
- 如何快速开发一个 Dubbo 应用?(含沙龙报名)
- es6 Proxy 简介
- linux noprobe参数,find 命令的参数详解
- nohup与区别于使用
- ValueError: Cannot feed value of shape (784,) for Tensor 'Placeholder:0', which has shape '(?, 784)'
- [安全攻防进阶篇] 八.那些年的熊猫烧香及PE病毒行为机理分析
- [深度学习从入门到女装]PReLU
- ESP8266自动下载电路分析
- 软件工程:数据流图和结构图怎么画?
- 物联网让生活更加轻松的五种方式
- MySQL-索引及其原理
- WindowManager LayoutParams 上
- 高人总结,告诉你输入输出阻抗是怎么回事?
- 加一度详解百度线索通,竞价新手必看福利!
- 分享一下身边朋友自学android开发及找工作的那些事!【不足勿喷】
- 有道打赏视频/支付已对接/自带资源
热门文章
- html制作网页案例代码-HTML5+CSS大作业——三八女人节主题设计(1页)-
- linux truncate 命令,如何在Linux中截断truncate文件
- 明日之后今天又又又更新了:熟练度溢出问题已解决,即将开放18庄?
- Web分辨率以及网页测试
- 用计算机学数学日记,【精华】小学生数学日记十篇
- PHP根据身份证号计算年龄和年龄分段
- 逝去的流年,渐行渐远,慢慢成为眼角的回忆
- CCS5.5 仿真配置文件操作说明
- Unity灯光效果及设置详解
- 电动自行车电池[充不进电][铅酸电池][饿死]重新激活