zl程序教程

您现在的位置是:首页 >  后端

当前栏目

《C++编程惯用法——高级程序员常用方法和技巧》——2.2 赋值

C++方法编程程序员 技巧 常用 高级 赋值
2023-09-11 14:17:39 时间

本节书摘来自异步社区出版社《C++编程惯用法——高级程序员常用方法和技巧》一书中的第2章,第2.2节,作者: 【美】Robert B. Murray ,更多章节内容可以访问云栖社区“异步社区”公众号查看。

2.2 赋值

和复制构造函数一样,如果我们没有声明赋值操作符函数,C++编译器会自动为我们合成一个。缺省的赋值操作符会为每个数据成员进行赋值。缺省的赋值操作符的适用场合和缺省的复制构造函数一样。如果缺省的复制构造函数是错误的,那么缺省的赋值操作符几乎也可以被确定为错误的(反之亦然)。

赋值操作符和复制构造函数通常都有着几乎同样的逻辑。它们之间的主要区别在于:

当对象被自赋值时,赋值操作符必须可以工作;
每次对赋值操作符的调用都会改写一个已经存在了的值。如果在被改写的对象中使用了对象外的资源,那么我们可能需要释放这些资源;
赋值操作符可以向外返回一个值。
下面是String类的复制构造函数和赋值操作符:

String::String(const String s)

: data(new char[strlen(s.data)+1]{

 strcpy(data,s.data);

const String 

String::operator=(const String s){

 if( s!= this){

 delete [] data;

 data = new char[strlen(s.data)+1];

 strcpy(data,s.data);

 return*this;

请注意上面的赋值操作符。其中对于 s和this的比较是为了防范如下的代码:

String s;

如果没有上面的比较,对于String对象的自赋值,我们将会先删除String中的数据,然后又试图对这些刚被删除的数据进行拷贝。我们在编写赋值操作符时,必须时刻考虑到自赋值的可能性,并确保自己的代码在这种情况下可能做出正常的反应(通常情况下是什么都不做)。我们可能不期望其他人编写这样的代码:

s = s;

但不管是使用引用还是指针的代码,我们必须保证它们拥有同样的效果。

一旦我们确信正在处理两个不同的对象,那么与复制构造函数不同的是,赋值操作符必须将原有值中所控制的资源释放掉。(这也就是我们代码中delete的作用。)在这之后,除那个返回值之外,赋值操作符的行为通常都和构造函数中的一致。我们通常都会把那个公有的逻辑提取出来放到一个私用的成员函数中去,并在复制构造函数和赋值操作符中调用这个函数;在本例中,这个公有的逻辑只是一个简单的函数调用,所以我们就直接复制了这个调用。

2.2.1 operator=的返回值

赋值操作符应该返回一个被赋值对象的常量引用。这使得用户可以写出如下的代码:

Complex x,y;

x = y = Complex(0,0);

被重载的操作符和内建的操作符有着同样的优先级和结合顺序。=是右结合的,所以下面的赋值:

y=Complex(0, 0);

将会被首先执行,它所产生的结果又将会被赋值给x。

通过返回一个常量引用,我们就可以阻止将赋值结果作为左值的做法:

(a=b)=c;

这样做不但看起来比较奇怪,它所产生的结果同样也会让人大吃一惊。例如,假设a和c都引用到同样的目的,这样做会导致什么结果呢?

让赋值操作返回一个值也有着一个缺陷:即使我们并不使用它,我们也需要用一些代码来返回这个值:

a = b;//返回值未被使用

在实践中,这种做法几乎都是可取的。那些额外的代码通常都是一条简单的机器指令(记住:我们返回的是一个引用,它实际上也就是个指针,而不是一个全新的对象)。在大部分情况下,由这一条指令带来的性能影响是可以忽略不计的。如果真的是十分注重效率的话,那么赋值操作符应该被定义为inline;在此时,任何一个还过得去的优化器都可以优化掉这条没有被使用的指令。


C++ 编程std::string类 td::string是C++标准库中的一个类,它用于表示字符串,在C++中是一个非常常用的数据类型。std::string可以保存任意长度的字符串,并且支持各种字符串操作,包括连接、查找、替换等等。
C++ Primer Plus 第6版 读书笔记(7)第 7 章 函数——C++的编程模块 乐趣在于发现。仔细研究,读者将在函数中找到乐趣。C++自带了一个包含函数的大型库(标准 ANSI 库加上多个 C++类),但真正的编程乐趣在于编写自己的函数;另一方面,要提高编程效率,本章和第 8 章介绍如何定义函数、给函数传递信息以及从函数那里获得信息。
来源于《高质量C/C++编程》的几道经典面试题 .str传给p的时候,p是str的临时拷贝,有自己的独立空间,当GetMemory函数内部申请了空间后,地址放在p中,str仍然是NULL。当Getmemory函数返回之后,strcpy拷贝的时候,形成了非法访问。
C++ 日期和时间编程总结 在 C++11 之前,C++ 编程只能使用 C-style 日期时间库,其精度只有秒级别,这对于有高精度要求的程序来说,是不够的。但这个问题在C++11 中得到了解决,C++11 中不仅扩展了对于精度的要求,也为不同系统的时间要求提供了支持。另一方面,对于只能使用 C-style 日期时间库的程序来说,C++17 中也增加了 timespec 将精度提升到了纳秒级别。
异步社区 异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。