-
运算符重载
-
运算符重载
-
运算符重载是具有特殊函数名的函数
函数名字为 返回类型 + operator(关键字) + 操作符 + ( 参数列表 )
举例: bool operator<( const A& s , const A& t ) //注意这个函数是放在全局的
编译器在看到 < 时 , 会去比较 < 符号两端的对象 , 若有一端为自定义类型的对象 , 则会去搜索是否有相应的函数(全局和类里面搜索) 如果没有就报错
请注意运算符重载可以分为两类
第一类是放在全局的 这类的函数 , 操作符左边的就是参数列表中的第一个,右边的就是参数列表中的第二个
举个例子
由于cout 不能自动打印自定义类型的变量,只能自己写,以及cin
第二类是放在类里面的,放在类里面的,一定要注意成员函数的第一个参数为隐藏的this指针
举个例子:
此时这里的 s < t 可以看成 s.operator<( t ) ,所以this指针就是&s
注意:.* :: sizeof ?: . 这五个运算符不能重载
-
赋值重载(六大成员函数之一)
-
赋值重载函数可以看成是特殊的一种运算符重载函数
如果让编译器自己生成,相当于拷贝构造函数(浅拷贝),如果要进行深拷贝,需自行处理
编译器自动生成的,对内置类型浅拷贝,对自定义类形调他的拷贝构造
相当于 void operator( A& s )
this->_year = s._year;
this->_month = s._month;
this->_day = s._day;
举个例子:
请注意:Date s( 2024 ,11,2 );
Date t = s;//这里是拷贝构造
-
const成员
-
const成员修饰this指针
如果*this指向的内容不能被修改 , 则可以加const
如果*this指向的内容能被修改,则不能加const
如果我们想要给类里面的函数中的 *this加上const怎么做呢
放回类型 + 函数名 + 参数列表 + const
取地址及const取地址操作符重载
-
取地址成员函数
下面介绍两个(取地址)默然成员函数
请注意 s 与 t 均执行第一个函数,因为 s 与 t 不是const 修饰
初始化列表
初始化列表主要是解决对象中变量的定义与初始化
我们逐级对初始化列表分析
首先A中没有默然构造函数,则要传递参数,对象s中的变量_a , _b , _c 在初始化列表中定义并初始化,用a给_a初始化,......
这两个代码等价
这里用了缺省参数,定义_a , _b , _c 时 , 由于没有任何操作,_a = 1 , _b = 0 , _c = 3
其中有三个地方必须用初始化列表
注意初始列表只能初始化一次
1.引用 2.const修饰的变量 3.没有默认构造函数的对象
注意:对象中内存储的顺序也就是对象中变量声明的顺序
s对象先储存_a , 在储存_b
隐式类型转换
单操作数隐式类型转换
这里的1会去构造一个对象,然后再将这个对象拷贝构造给s(注意这个对象具有常性) 因此这个代码正确
如果你不想让隐式类型转换发生
则可以在构造函数前加一个explicit(关键字)
多操作数隐式类型转换
加 { }
静态成员变量和静态成员函数
若想将一个变量设置成全局的并且是类成员变量,就可以使用static
class A
{
public:
A()
{
num++;
}
A(const A& s)
{
num++;
}
//访问静态成员变量,可以用静态成员函数
//静态成员函数没有this指针
static int GetNum()
{
return num;
}
private:
//静态成员变量,不是属于某一个变量,而是属于整个类
//这里是声明,静态成员变量不在初始化列表定义初始化,原因:静态成员变量不属于对象中的成员变量,而是类的成员变量
static int num;
};
//这里是定义,初始化的地方
int A::num = 0;
int main()
{
A s;
cout << s.GetNum() << endl;
return 0;
}
总结:若想访问静态成员变量,突破类域即可