C++学习(6)--转向effective c++(2)

本文深入探讨了C++编程中的关键技巧,包括自定义拷贝构造函数和赋值操作符的重要性,如何正确使用成员初始化列表,以及在实现赋值操作符时需要注意的问题。文章强调了避免内存泄漏和对象身份问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符
看到这个就开始恨他妈的《高质量c++编程了》
这次搞明白了,之所以要自定义一个赋值操作符,比如建立了两个对象a和b,其成员为指针
当执行b=a的时候,相当于b的指针指向了a,那么b原来指向的咚咚不会被删除,造成内存泄漏
而且因为a,b指向同一地,那么只要其中一个离开了它的生存空间,其析构函数就会删除掉另一个指针还指向的那块内存。
如果俺做的类根本不需要进行拷贝和赋值咋办?
直接把这俩构造函数声明一下放到私有成员里面。就算俺想调用都不行~嘿嘿!!
总之结论是:只要类里有指针时,就要写自己版本的拷贝构造函数和赋值操作符函数。

条款12: 尽量使用初始化而不要在构造函数里赋值
《高》我*你**!!
回到那个问题,给构造函数赋值是用初始化列表还是直接在函数体内赋值
养成尽可能使用成员初始化列表的习惯,不但可以满足const和引用成员初始化的要求,还可以大大减少低效地初始化数据成员的机会。
至于另一种方法为什么会低效,听我慢慢道来~
……
太长了,不道了,总之后者在一些情况下调用的成员函数会多于前者,ok?
养成尽可能使用成员初始化列表的习惯,不但可以满足const和引用成员初始化的要求,还可以大大减少低效地初始化数据成员的机会。
加一句:请注意static类成员永远也不会在类的构造函数初始化。(莫名其妙……)
条款13: 初始化列表中成员列出的顺序和它们在类中声明的顺序相同
看题目还以为就只是个格式的说明,不过竟然有很大的知识量呐!
这个知识是:
类成员是按照它们在类里被声明的顺序进行初始化的,和它们在成员初始化列表中列出的顺序没一点关系。
对的,如果类的每个对象都要按他们各自的初始化顺序的话,会很费开销的~所以要遵从类本身声明的顺序。

条款15: 让operator=返回*this的引用
w = x = y = z = "hello";等价于
w = (x = (y = (z = "hello")));等价于
w.operator=(x.operator=(y.operator=(z.operator=("hello"))));
试想如果返回一个void……那么…………
结论是,这种情况下你将别无选择:当定义自己的赋值运算符时,必须返回赋值运算符左边参数的引用,*this。如果不这样做,就会导致不能连续赋值,或导致调用时的隐式类
型转换不能进行,或两种情况同时发生。
看他那一大串解释,我突然觉得自己有必要看看编译原理了……

条款16: 在operator=中对所有数据成员赋值
这个是当然的,做戏要做全套么,要记住:
类里增加新的数据成员时,也要记住更新赋值运算符函数。
但对于派生类的赋值运算符来说,就比较麻烦了:
因为派生类的赋值运算符也必须处理它的基类成员的赋值
又因为基类成员是私有的……所以必须在derived的赋值运算符里显式地对derived的base部分赋值。
这个调用和一般情况下的在成员函数中调用另外的成员函数一样,以*this作为它的隐式左值。
后面还有些东西先不看了,怪怪的
条款17: 在operator=中检查给自己赋值的情况
面临的这个问题学术上称为object identity,它在面向对象领域是个很有名的论题。
简单的解决方法是
一,比较对象
// 检查对自己赋值的情况
  if (*this == rhs)            // 假设operator=存在
    return *this;
二,比较地址
& c::operator=(const c& rhs)
{
  // 检查对自己赋值的情况
  if (this == &rhs) return *this;
  ...
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值