❥关于C++之类的复制构造函数&赋值运算符
Posted itzyjr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了❥关于C++之类的复制构造函数&赋值运算符相关的知识,希望对你有一定的参考价值。
C++自动提供了下面这些成员函数:
- 默认构造函数,如果没有定义构造函数
- 默认析构函数,如果没有定义
- 复制构造函数,如果没有定义
- 赋值运算符,如果没有定义
- 地址运算符,如果没有定义
一、复制构造函数
复制构造函数用于将一个对象复制到新创建的对象中。
类的复制构造函数原型:_Class(const _Class &);
它接受一个指向类对象的常量引用作为参数。例如,StringBad类的复制构造函数的原型如下:
StringBad(const StringBad &);
何时调用复制构造函数?
StringBad ditto(motto); // 调用StringBad(const StringBad &)
StringBad metoo = motto; // 调用StringBad(const StringBad &)
StringBad also = StringBad(motto); // 调用StringBad(const StringBad &)
StringBad *pStringBad = new StringBad(motto); // 调用StringBad(const StringBad &)
如果重载了operator+(),则下面语句将调用复制构造函数:
StringBad x, y, z;
x + y = z; // x + y创建临时对象再被赋值z,创建临时对象时调用StringBad(const StringBad &)
每当程序生成了对象副本时,编译器都将使用复制构造函数。
在下述情况下,将使用复制构造函数:
- 将新对象初始化为一个同类对象;
- 按值将对象传递给函数;
- 函数按值返回对象;
- 编译器生成临时对象。
实现一个复制构造函数:
StringBad::StringBad(const StringBad & st)
num_strings++; // 处理静态成员的更新
len = st.len;
str = new char[len + 1]; // 分配空间
std::strcpy(str, st.str); // 复制字符串到新地址
cout << num_strings << ":\\"" << str << "\\" object created\\n";
二、赋值运算符
并不是程序清单的所有问题都可以归咎于默认的复制构造函数,还需要看一看默认的赋值运算符。ANSI C允许结构赋值,而C++允许类对象赋值,这是通过自动为类重载赋值运算符实现的。这种运算符的原型:_Class & _Class::operator=(const _Class &);
它接受并返回一个指向类对象的引用。例如,StringBad类的赋值运算符的原型如下:
StringBad & StringBad::operator=(const StringBad &);
不要将赋值与初始化混淆了:
Star sirius;
Star alpha = sirius; // 初始化为一个对象
Star dogstar;
dogstar = sirius; // 赋值
如果语句创建新的对象,则使用初始化;如果语句修改已有对象的值,则是赋值。
何时调用赋值运算符?
将已有的对象赋给另一个对象时,将使用重载的赋值运算符:
StringBad headline1("Celery Stalks at Midnight");
...
StringBad knot; // 自动调用默认构造函数初始化knot
knot = headline1; // 赋值运算符被调用
初始化对象时,并不一定会使用赋值运算符:
StringBad metoo = knot; // 使用复制构造函数,也可能使用的是赋值运算符
与复制构造函数相似,赋值运算符的隐式实现也对成员进行逐个复制。对象赋值是通过默认赋值运算符函数实现的(如果没有重载),把对象A的数据成员的值逐位赋值给对象B,两个对象之间的赋值,仅仅使用这些对象中数据成员,而两个对象仍是分离的。如果成员本身就是类对象,则程序将使用为这个类定义的赋值运算符来复制该成员,但静态数据成员不受影响。
实现一个赋值运算符:
StringBad & StringBad::operator=(const StringBad & st)
if (this == &st)
return *this;
delete[] str;
len = st.len;
str = new char[len + 1];
std::strcpy(str, st.str);
return *this;
由于赋值运算符,是处理对象的复制,将对象的字段深度复制过来即可,不涉及创建新对象,所以实现代码里没有 num_strings++; 这样的代码。但对于自定义的复制构造函数而言,不管是临时对象,还是用另一对象初始化一个对象,都涉及创建新对象,所以有代码 num_strings++; 方便跟踪以及计数逻辑。
以上是关于❥关于C++之类的复制构造函数&赋值运算符的主要内容,如果未能解决你的问题,请参考以下文章