一个空类含有的函数:
class Empty{
};
// 等价于
class Empty{
public:
Empty(){ //默认构造函数
}
Empty(const Empty& rhs){ //拷贝构造函数
}
~Empty(){ //析构函数
}
Empty& operator=(const Empty rhs){ //重载赋值操作符函数
}
Empty* operator & (); // 取址运算符
const Empty* operator & () const; // 取址运算符const
};
这些函数只有在被调用的时候才会被编译器创建出来。
Empty e1; // 默认构造函数
Empty e2(e1); // 拷贝构造函数
e2 = e1; //重载赋值操作符
拷贝构造函数和重载赋值操作符函数用于将来源对象的每一个非静态成员变量拷贝到目标对象。
如果类中含有指针型的数据成员、需要使用动态内存,程序员最好显式定义自己的复制构造函数,避免各种可能出现的内存错误。
默认的拷贝构造函数是浅拷贝,可能导致两个指针指向了堆里的同一个空间,在销毁对象时,两个对象的析构函数将对同一个内存空间释放两次,从而引发错误。
对于对象中动态成员,就不能简单赋值,而应该重新动态分配空间。
class Rect{
public:
Rect() // 构造函数,p指向堆中分配的一空间
{
p = new int(100);
}
Rect(const Rect& r)
{
width = r.width;
height = r.height;
p = new int; // 为新对象重新动态分配空间
*p = *(r.p);
}
~Rect() // 析构函数,释放动态分配的空间
{
if(p != NULL)
{
delete p;
}
}
private:
int width;
int height;
int *p; // 一指针成员
};