构造函数简图
析构函数简图
拷贝构造函数简图
运算符重载简图
赋值运算符重载与拷贝构造函数的区别
- = 即为赋值运算符
- 这涉及到两个已经存在的实例化对象之间的复制拷贝。
- 这个与拷贝构造函数是完全不一样的,拷贝构造函数它的本质上就是一个构造函数,主要是用一个已经存在的实例化对象去初始化另外一个实例化对象。
- 这个确实与拷贝构造函数很容易发生混淆,拷贝构造函数主要是针对类的实例化对象,在进行函数的传值调用与传值返回的时候会发生调用拷贝构造函数,因为在进行实例化对象的参与到函数的传值调用与传值返回的时候,在这两者过程当中都会有新的实例化对象的生成,那也就需要去调用构造函数,即拷贝构造函数
- 但是实例化对象之间的赋值就并不是这样子,因为在赋值的过程当中并没有发生新的实例化对象的生成,而是两个已有已存在的是实例化对象之间的赋值拷贝,也就是说在这个过程当中并没有新的实例化对象的生成,既然没有类的实例化对象的创建,并且由于构造函数只在对象的生命周期内只调用一次,所以在赋值的时候跟构造函数没有任何一点关系,这边的主角是运算符重载函数,也就是对赋值运算符=进行运算符重载
赋值运算符重载
- 然后在类当中去实现成员函数operator=的时候,值得注意的是:隐藏的this指针,并且由于在c语言当中是支持连等的,我们这个运算符重载函数,最好也是需要能够支持这一点,这也就意味着对于这个函数的返回类型不能是void之类,需要返回一个类的实例化对象,如果说返回的真的是一个实例化对象的话,那么这时候又会发生拷贝构造函数的调用,会影响效率,于是这时候就采用函数的引用返回。
- 当然还有一个小点就是说如果是自己给自己赋值的话,这是没有任何必要的,所以说可以用if去判一下
- 然后由于赋值运算符重载函数也是一个默认成员函数,所以说如果你没有去显示实现的话,编译器也会默认去生成一个,但是对于编译器默认生成的赋值运算符重载函数,对于实例化对象当中的内置类型的成员仅仅会进行最直白而简单的浅拷贝/值拷贝,然后对于实例化对象当中的自定义类型成员则会去调用对应自定义类型成员的赋值运算符重载函数,麻雀虽小五脏俱全
- 但有时候这样子是可能会出问题的,对于拷贝构造函数那边道理是类同的,所以说如果对于那些类的实例化对象当中有申请资源的那种实例化对象,比如说自己模拟栈,那么这时候还是需要去自己实现赋值运算符重载函数
- 然后由于这个赋值运算符重载函数他是属于类的一个默认成员函数,然后对于类的默认成员函数的话是不能够给他放到全局里面去的,也就是说是只能够给他在类的里面,因为如果你把它给他弄到全局去的话,那么在类当中就没有该默认成员函数,那么就会自己默认生成一个,那这样子去全局的那个就会发生冲突。所以说对于默认成员函数的话,它本质上也是类当中的一个成员函数,因此是绝对不可以给他放到全局里面去。当然在类当中去声明该函数,然后定义的话写在全局那边(加上域作用限定符),这是完全可以的
- 示例:
Stu& operator=(const Stu& x2)
{
if (&x2 != this)
{
memcpy(name, x2.name, sizeof(char) * 10);
age = x2.age;
score = x2.score;
}
return *this;
}
赋值运算符只能重载成类的成员函数不能重载成全局函数
前置++与后置++的重载
- 前置++与后置++的区别就在于:对于前置++而言是先给他加上一再去使用那个值,对于后置++而言的话是先去使用那个值,然后再把那个值给他加上一,这个就是这两个运算符没有被重载之前的所表达的含义,并且他们的操作数往往都是整数
- 我现在如果说想要把这两个操作符给他重载一下的话,首先必须得明白什么是运算符的重载,其实根本的目的就在于想要把这个运算符它所能适配的操作数的类型范围给他进行扩大,而不仅单单就是一个整数,比方说对于某些类的实例化对象也可以使用这个操作符,但当然不是说对于这个类的实例化对象给他去+1,这样也没有任何实际的意义,所以说这个前置++与后置++运算符重载之后如果说类的实例化对象想要去使用前置++或后置++,可能它的作用就在于对于其中的某个成员变量去进行前置++或者后置++等等等等
- 但是因为如果说没有进行特殊规定的话,你会发现这两个操作符前置++和后置++他们进行重载的时候是没有办法进行很好的一个区分,所以C++规定:后置++重载时多增加一个int类型的参数,但调用函数时该参数不用传递,编译器自动传递
- 代码样本:
#include <iostream>
using namespace std;
class Stu
{
public:
void show()
{
cout << age << " " << score << endl;
}
void input()
{
cin >> age >> score;
}
Stu operator++(int)
{
Stu tmp = *this;
age++;
return tmp;
}
Stu& operator++()
{
age++;
return *this;
}
private:
int age = 0;
double score = 0;
};
int main()
{
Stu s1;
Stu s2;
s1.input();
s2.input();
(s1++).show();
(++s2).show();
return 0;
}