一、静态成员
什么是静态成员:
被static修饰的成员变量和成员函数就叫静态成员
普通成员的特点:
成员变量:每个类对象中都有一份属于自己的成员变量,相互之间没有关联、独立的
成员函数:隐藏着一个this指针,接收调用者的地址用于区分调用者
静态成员的特点:
静态成员变量:
1、存储在data或者bss内存段中,一个类中的所有静态成员变量只有唯一一份,被所有类对象共享
2、一旦成员变量被声明为静态成员变量后,通过sizeof计算类字节数时,就不统计该变量的字节数
3、静态成员变量必须在类内加static声明,在类外单独定义、初始化,定义时无需加static
4、静态成员变量的生命周期不再依赖于某个类对象,伴随整个程序生命周期
5、因为静态成员变量的存在不依赖于任何类对象,所以可以无需实例化类对象,直接访问静态成员变量
对象名.成员变量/静态成员变量
对象名->成员变量/静态成员变量
类名::静态成员变量 (无需实例化对象,但是一般成员变量都是私有的)
静态成员函数:
1、没有隐藏的this指针,所以在静态成员函数中无法直接访问普通成员变量、普通成员函数,但是手动传递对象的地址间接访问,毕竟静态成员函数还是属于类的
2、但是可以直接访问静态成员变量、静态成员函数
3、调用方式
对象名.成员函数()/静态成员函数()
对象名->成员函数()/静态成员函数()
类名::静态成员函数() (无需实例化对象)
静态成员的作用:
1、静态成员相当于多了一层类作用域的全局变量、全局函数
2、静态成员变量适合存储所有类对象的公共属性,从而节约资源(税率、利率等)
3、静态成员函数可以当做访问私有的静态成员变量的公开接口,一方面不破坏类的封装性,另一方面可以无需实例化对象也能调用类的静态成员,让类本身具有管理自己成员的能力
二、单例模式
什么是单例模式:只能实例化一个类对象
什么场景下使用单例模式:
进程管理器、日志管理器
网站访问计数器、应用配置程序
线程池、服务器的连接管理器
实现单例模式的原理:
1、禁止在类外随意实例化对象,把构造函数\拷贝构造私有化
2、确保类对象只有一份,在类中定义一个静态的类对象成员变量
3、提供一个获取静态类对象成员变量的公开的接口,设计静态成员函数用于获取那唯一的一个静态类对象
饿汉模式的单例:
程序运行开始时就立即实例化单例类对象,不管后期是否用得到都会完成实例化
优点:不可能被多个线程同时运行创建多份(线程安全)
缺点:如果后期使用不到,就浪费时间、资源
懒汉模式的单例:
什么时候使用,什么时候才去实例化单例类对象
优点:使用时才会创建,节约时间、资源
缺点:可能会被多个线程同时实例化,有可能会创建出多个单例类对象(线程不安全)
三、运算符函数
在C++中会把运算符当做函数处理,一个表达式,其实可能调用了很多运算符函数来完成计算,这种特性对内建类型没有用,但是对于自建类型而言,通过设计运算符函数能够进行个性化运算,以此提高代码的可读性、易用性,例如string类
string str;
str += "hehe"; strcat(str,"hehe");
str == str1; strcmp(str,str1);
运算符函数的格式:#表示运算符 O表示运算符对象 []代表返回值不确定
单目运算符: #O O#
成员函数:
[] O::operator#(void)
{
}
返回值不确定,唯一的参数就是调用者本身
全局函数:
[] operator#(O& o) // o引用取别名
{
}
某种运算符成员函数、全局函数只能同时实现一个,不能一起实现
双目运算符: a # b
注意:左操作数是运算符函数的发起者
成员函数:
[] A::operator#(B& b)
{
}
全局函数:
[] operator#(A& a,B& b)
{
}
设计一个坐标类
Point
{
int x;
int y;
}
Point p1(1,1),p2(2,2);
p1 + p2;
p1 - p2;
四、运算类的双目运算符 O是类名
成员函数:a + b
const O O::operator+(const O& b)const
{
return O(x+b.x,y+b.y); //创了一个匿名的对象 可以忽略不写 直接返回
}
全局函数: a + b
const O operator+(const O& a,const O& b)
{
return Point(a.x+b.x,a.y+b.y);
}
友元:
在实现类的全局运算符函数时,可能会使用到类内的私有成员,此时全局函数是没有访问权限,如果改变私有为公开会破坏类的封装性,如果提供公开的访问函数又非常麻烦,最好的方式是给该全局函数给与独家授权让其能够访问类内私有成员,这种行为称把该全局函数设置为友元函数
方式:在类内对全局函数声明,并在声明前加 friend
friend const O operator+(const O& a,const O& b);