类的6个默认的成员函数包括:
构造函数、析构函数、拷贝构造函数、赋值运算符重载函数、取地址操作符重载、const修饰的取地址操作符重载。
以下详细介绍前四个函数。
一、构造函数
构造函数:初始化对象的内存地址空间。
CGoods()
{
_name=new char[1];
}
实例化一个对象:
1、分配对象内存空间
2、调用对象的构造函数
初始化:定义的同时赋值。
赋值:定义后,再赋值。
构造函数以类名为函数名,无返回值,可以重载可以带参数,在实例化一个对象的时候系统自动调用
如果用户自己没写构造函数,系统会调用系统默认的构造函数,系统默认的函数是public和inline的
二、析构函数
析构函数:释放对象的内存空间所占的资源(堆内存资源、文件描述符等)
~CGoods()
{
delete []_name;
_name=NULL;
}
销毁一个对象
1、调用析构函数清理对象所占资源
2、清理内存空间
析构函数在类名前加上~运算符,无返回值,不带参数不可以重载,在return后由系统自动调用
注意:手动调用析构函数=调用一个普通函数,清理内存空间后系统还会自动调用一次析构函数,因此不建议手动调用析构函数。
后构造的函数先析构,先构造的函数后析构,与栈相似。
三、拷贝构造函数
拷贝构造函数:用一个已经存在的对象初始化相同类型的新对象时调用的函数
对象自己的成员,可以任意访问自己的其他任何访问限定成员方法和成员变量
CGoods(const CGoods &rhs) //必须传引用,为了防止实参和形参递归构造
{
_name=new char[strlen(rhs._name)+1]; //防止浅拷贝
strcpy(_name,rhs._name);
_amount=amount;
_price=price;
}
const的作用:
1、修饰形参不能改变
2、接收隐式产生的临时量
浅拷贝:多个对象指向同一个资源
int *p=new int(50);
int *q=p;
int q1=q;
深拷贝:多个对象拥有各自的资源
int *p=new int(50);
int *q=new int();
*q=*p;
四、赋值运算符重载函数
赋值运算符重载函数:用已存在的对象给另一个已存在的对象赋值
void Operator(const CGoods &rhs) //可以值传递但是引用效率高,因为没有开辟新栈帧
{
if(this==&rhs) //防止自赋值
{
return;
}
delete []_name;
_name=new char[strlen(rhs._name)+1];
strcpy(_name,rhs._name);
_amount=rhs._amount;
_price=rhs._price;
}
系统提供的赋值运算符重载函数:
1、多次释放同一资源
2、内存泄漏
自定义的赋值运算符重载函数:
1、防止自赋值
2、释放旧资源
3、开辟新资源进行初始化
系统提供的拷贝函数都是浅拷贝,如果发生浅拷贝,应该自己提供构造函数、拷贝构造函数、赋值运算符重载函数
编译器编译类分为三步:
1、先扫描类名
2、再扫描所有的成员变量
3、最后再扫描所有的方法体和形参的默认值