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