构造函数名与类名相同。 函数没有函数返回值,就是将返回值说明成void也不行 。 构造函数一般声明为公有成员,但是它不能被显式地调用。 构造函数的主要目的是为对象分配空间,进行数据成员的初始化。 如果用户没有显式地在类中写出构造函数,那么系统会为该类自动生成一个默认的构造函数。这个默认构造函数的形式如下:
类名::类名()
{ ...}
构造函数可以被重载,这在工程上十分常见。
CStudent::CStudent()
{
strcpy(m_strName, "");
strcpy(m_strID, "");
m_cSex = '0';
strcpy(m_strMajor, "");
}
CStudent(char *strname,char *strID,char csex,char *strmajor)
{
strcpy(m_name,strname);
strcpy(m_ID,strID);
m_sex = csex;
strcpy(m_major,strmajor);
}
主函数如下:
void main()
{
//CStudent student1;
//student1.SetName("张三");
//student1.SetID("23433");
//student1.SetSex('0');
//student1.SetMajor("物理");
CStudent student1("张三","53413",'0',"shuxue");
char strname[20];
char strid[12];
char csex;
char strmajor[20];
student1.GetName(strname);
student1.GetID(strid);
student1.GetSex(&csex);
student1.GetMajor(strmajor);
cout<<"该学生信息为:"<<endl;
cout<<"姓名为:"<<strname<<" "<<"编号为:"<<strid<<" "<<"性别为:"<<endl;
if(csex == 0)
{
cout<<"男 "<<endl;
}
else
cout<<"女 "<<endl;
cout<<"专业为: "<<strmajor<<endl;
}
注意:
(1)如果用户没有显式地定义类的构造函数,系统会生成一个函数体为空的构造函数。但是,一旦类中已经定义了一个构造函数(无论它是什么形式的),系统就不再提供默认的构造函数。 如果在本例中没有定义不带参数的构造函数,那么下面的语句就会出现编译错误。
CStudent Student2; //错误,系统找不到对应的构造函数。
(2)当使用不带参数的构造函数创建对象时,应使用下面形式的语句:
CStudent Student2; 而不能写成: CStudent Student2();
这是因为系统会把上面的语句解释成一个名称为Student2的普通函数的原型声明,该函数的返回值是CStudent类型。
二.析构函数
析构函数(destructor function)作用与构造函数相反,用于释放为对象分配的存储空间,在对象被删除之前进行内存清理工作或数据保存工作。 例如,可以在析构函数中释放由new运算符分配的内存,在Windows窗口被关闭时通过析构函数保存窗口的内容。
~CStudent();
首先,将学生类的变量名设置为指针类型
private:
//char m_name[20];
//char m_ID[20];
//char m_sex;
//char m_major[20];
char *m_name;
char *m_ID;
char m_sex;
char *m_major;
这样子,各个变量的长度就不是固定的。
CStudent::CStudent(char *strname,char *strID,char csex,char *strmajor)
{
m_name = new char[strlen(strname)+1];
strcpy(m_name,strname);
m_ID = new char[strlen(strID)+1];
strcpy(m_ID,strID);
m_sex = csex;
m_major = new char[strlen(strmajor)+1];
strcpy(m_major,strmajor);
}
CStudent::~CStudent()
{
delete []m_name;//////数组指针占用的内存不会自动释放,所以需要手动释放
delete []m_ID;
delete []m_major;
}
关于析构函数的方法:
(1)析构函数的名称是在类名前面加上波浪号“~”构成,即“~类名”。
(2)析构函数没有参数,因此不能被重载。每个类只能有一个析构函数。
(3)析构函数没有函数返回值,不能将其返回值说明成void类型。
(4)对象在被撤销时(生命期结束时),系统会自动调用该对象所对应的析构函数。另外,如果一个对象是通过new运算符动态生成的,那么在通过delete运算符释放该对象时,会自动调用析构函数。
(5)每个类都必须有一个析构函数,如果没有显式地定义析构函数,那么编译系统会自动生成一个默认析构函数。默认析构函数的函数体是空的。该默认析构函数的目的是释放对象所占据的存储空间。
三。拷贝构造函数
拷贝构造函数是一种特殊的构造函数。它的用途是:当创建一个新对象时,使用一个已经定义的对象去初始化这个新对象。例如: CPoint point2(point1); 或 CPoint point2 = point1;
类名(const 类名 &引用对象名) ;
拷贝构造函数被调用的三种情况 :
(1)当使用某类的一个已存在的对象去初始化该类的另一个对象时。例如: CStudent Student2(Student1); 或 CStudent Student2 = Student1;
(2)当函数的形参是某类的对象时,在调用该函数时,实参对象向形参对象传递值,需要调用拷贝构造函数。
(3)如果函数的返回值是某类的对象,那么在函数调用时,会调用拷贝构造函数,以把返回值对象复制给一个系统生成的临时对象。