十七、拷贝构造和拷贝赋值
1、深拷贝和浅拷贝
拷贝构造:
1)如果一个类包含指针形式的成员变量,缺省的拷贝构造函数只会复制指针本身,而不会复制指针所指向的内容,这种拷贝称为浅拷贝。
2)浅拷贝将导致不同对象间的数据共享,如果数据是在堆区,在析构时会引发"double free"
异常;
3)因此必须定义一个支持复制指针所指向内容的拷贝构造函数,即深拷贝。
拷贝赋值:
在类中编译器会提供一个缺省的拷贝赋值操作符函数,完成两个对象的赋值操作,但是和缺省拷贝构造类似,是浅拷贝。为了得到深拷贝的效果,必须自己定义一个支持深拷贝的拷贝赋值函数。
类型& operator=(const 类名& that){
1)防止自赋值
2)分配新资源(类似买手机,新手机到了,再扔旧手机,更妥当些)
3)释放旧资源
4)拷贝新数据
5)返回自引用
}
练习:实现string类
十八、静态成员(static)
1、静态成员变量
class 类名{
static 数据类型 变量; // 声明
};
数据类型 类名::变量 = 初值; // 定义和初始化
1)静态成员变量类似全局变量,内存在全局区,所以它不属于对象,也不能在构造函数中定义和初始化,需要在类的外部单独定义和初始化。
2)使用方法
类名::静态成员变量;
(常用)
对象.静态成员变量;
2、静态成员函数
class 类名{
static 返回类型 函数名(形参表){..};
};
1)在静态成员函数中没有this指针;
2)使用方法:
类名::静态成员函数(实参表);
(常用)
对象.静态成员函数(实参表);
注意:
静态成员函数中只能访问静态成员,而在非静态成员函数既能访问静态成员,也能访问非静态成员。
3、单例模式
一个类只允许创建一个对象。
1)禁止在类的外部随意创建对象:私有化构造函数;
2)在类的内部自己维护唯一的对象:静态成员变量;
3)提供获取和访问该对象的方法:静态成员函数;
class A{
public:
A& get(void){
return a;
}
private:
A(void);
A(const A&);
static A a;
};
4)创建方式:
a. 饿汉式:无论单例对象用或不用,程序启动即创建;
b. 懒汉式:单例对象用的时候再创建,不用时即销毁;
练习1:自己写一遍String的实现;
练习2:自己实现单例模式 . .