C++基础(7)构造函数与析构函数

       构造函数名与类名相同。 函数没有函数返回值,就是将返回值说明成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)如果函数的返回值是某类的对象,那么在函数调用时,会调用拷贝构造函数,以把返回值对象复制给一个系统生成的临时对象。

猜你喜欢

转载自blog.csdn.net/shenseyoulan/article/details/81188089