自己没有写这些函数时,系统会自己提供一个,如果自己写,就不会提供
一、四个默认的函数
一、构造函数
对象的生成:对象开辟内存, 调用构造函数
先构造的后析构(在栈上, )
1、作用:初始化对象的内存空间
2、特点:
(1)可以重载
重载的三要素:同名、不同参、同作用域
(2)不能手动调用
类的成员方法,依赖对象来调动
原因:对象的生成有两步,一是开辟内存,二是调用构造函数对内存进行初始化。要先生成对象, 再调用构造函数,如果手动调用对象将无法生成。
二、析构函数
对象的销毁,调用析构函数(堆),释放对象所占的内存(栈)
1、作用:
释放对象所占的其他资源
2、特点
(1)不可重载
(2)可以手动调用(手动调用会退化成普通的函数调用)
三、拷贝构造函数
1、作用:
用一个已存在的对象来生成相同类型的新对象
2、函数原型
比如学生类的拷贝构造函数
Student(const Student & rhs);
3、特点
(1)形参一定要用引用(如果不是引用,实参传形参的过程又要调用拷贝构造函数,因此一直生成不了形参对象
(2)默认的拷贝构造函数是浅拷贝(遇到delete时会出错)
四、赋值运算符的重载函数
1、作用
用一个已存在对象给一个已存在的对象赋值
2、函数体
(1)自赋值判断‘’
(2)释放旧资源
(3)开辟新资源
(4)赋值
3、返回值 *this
4、特点:
形参要使用常引用,因为
(1)、防止实参修改形参
(2)、接收隐式生成的临时对象
系统默认的赋值运算符的重载函数时浅拷贝
二、this指针 指向对象的内存
普通的成员方法中,都有一个this指针,在操作成员时默认都是用this指针访问
构造和析构中,都有this指针
类型 类名称 * const this
代码如下:
class CGoods
{
public:
CGoods(char* name, int amount, float price)
{
std::cout << this << " :CGoods::CGoods(char*,int,float)" << std::endl;
mname = new char[strlen(name) + 1];
strcpy(mname, name);
mamount = amount;
mprice = price;
}
CGoods()
{
std::cout << this << " :CGoods::CGoods()" << std::endl;
mname = new char[1];
}
CGoods(float price)
{
std::cout << this << " :CGoods::CGoods(float)" << std::endl;
mname = new char[1];
mprice = price;
}
CGoods(const CGoods& rhs)
{
std::cout << this << " :CGoods::CGoods(const CGoods& )" << std::endl;
mname = new char[strlen(rhs.mname) + 1];
strcpy(mname, rhs.mname);
mamount = rhs.mamount;
mprice = rhs.mprice;
}
CGoods& operator=(<font color = "red">**const**</font> CGoods& rhs)
{
std::cout << this << " :CGoods::operator=(const CGoods&) <<==" << &rhs << std::endl;
if (this != &rhs)
{
delete[] mname;
mname = new char[strlen(rhs.mname) + 1];
strcpy(mname, rhs.mname);
mamount = rhs.mamount;
mprice = rhs.mprice;
}
return *this;
}
~CGoods()
{
std::cout << this << " :CGoods::~CGoods()" << std::endl;
delete[] mname;
mname = NULL;
}
private:
char* mname;
int mamount;
float mprice;
};
int main()
{
<font color = "green"> CGoods good1;
good1 = 19.5;</font> //隐式生成临时对象
//CGoods good = CGoods(19.5);
//CGood good = 19.5 CGoods tmp(19.5)
return 0;
}