构造函数:
C++类的目标之一是让使用类对象就像使用标准类型一样,事实上它并不能像初始化int类型那样初始化类对象,也就是说,常规的初始化语法不适用于类对象。为此,C++提供了一个特殊的成员函数——类构造函数。它是一种特殊的类成员函数,在创建类对象时被调用。通常,构造函数用于初始化对象的成员。
规则:
·构造函数的名称和类名相同,通过函数重载,可以创建多个同名的构造函数
·构造函数没有声明类型。初始化与构造函数的参数列表相匹配。
·如果不实现构造函数,编译器会生成一个默认构造函数;如果自己实现,则编译器不会生成。
系统默认的构造函数:
类名()
{
}
创建不同的构造函数,系统是以怎样的方式调用的?
#include<iostream>
class CGoods
{
public:
CGoods(const char* name, double price, int amount)//带有三个参数的构造函数
{
std::cout << this << " :CGoods::CGoods(char*,float,int)" << std::endl;
mname = new char[strlen(name) + 1]();
strcpy(mname, name);
mprice = price;
mamount = amount;
}
CGoods(const char* name, double price)//带有两个参数的构造函数
{
std::cout << this << " :CGoods::CGoods(char*,float)" << std::endl;
mname = new char[strlen(name) + 1]();
strcpy(mname, name);
mprice = price;
}
CGoods(int amount)//带有一个整形参数的构造函数
{
std::cout << this << " :CGoods::CGoods(int)" << std::endl;
mname = new char[1]();
mamount = amount;
}
CGoods()//不带参数的构造函数
{
std::cout << this << " :CGoods::CGoods()" << std::endl;
mname = new char[1]();
}
~CGoods()
{
std::cout << this << " :CGoods::~CGoods()" << std::endl;
delete[] mname;
}
private:
char* mname;
double mprice;
int mamount;
};
int main()
{
CGoods good1("car1", 10.1, 10);
CGoods good2("car1", 15.1);
CGoods good3(20);
CGoods good4;
return 0;
}
程序运行结果:
结论:
调用构造函数时,系统会选择函数形参列表与定义对象时的实参列表相匹配的那个构造函数进行调用。
对象的生成:
1)开辟内存 2)赋资源(内存空间进行初始化)
思考:构造函数能否手动调用对象?
不能手动调用对象,因为构造函数是生成对象的一环,无法使用对象来调用构造函数,在构造函数生成对象之前,对象是不存在的,就像父子,没有父,便没有子。即构造函数被用来创建对象,而不能通过对象来调用。
析构函数:
完成清理工作,对象生命周期结束时,程序自动调用一个特殊的类成员函数,即析构函数。析构函数名称前面加个~,和构造函数一样,析构函数没有返回类型,也没有参数。每个类只有一个析构函数。
系统默认的析构函数:
如果构造函数没有使用new,只需编译器生成一个什么都不用做的析构函数即可。
~类名()
{
}
如果构造函数使用new来分配内存,则必须使用delete提供的析构函数释放这些内存。
~CGoods()
{
delete[] mname;
mname=NULL;
}
对象的销毁:1)释放资源 2)释放空间
思考:析构函数能否手动调用对象?
可以手动调用对象。
注意:先构造的后析构,后构造的先析构。