这节讲解构造函数和析构函数
构造函数
构造函数是一个与类名相同的方法,它可以没有参数,也可以有一个或多个参数。如果构造函数没有参数,该构造函数为默认构造函数。
举例 默认的构造函数
class A { private: char m_Username[128]; char m_Password[128]; public: A() { strcpy(m_Username,"MR"); strcpy(m_Password,"KJ"); cout<<"构造函数被调用!"<<endl; } char* GetUsername() const { return(char*)m_Username; } char* GetPassword() const { return(char*)m_Password; } }; int _tmain(int argc, _TCHAR* argv[]) { A a1; //定义A的对象,调用默认构造函数 A * pa = new A(); //定义A的对象,调用默认构造函数 delete pa; //释放pa return 0; }
示例:调用有参的构造函数
class A { private: char m_Username[128]; char m_Password[128]; public: A() { strcpy(m_Username,"MR"); strcpy(m_Password,"KJ"); cout<<"构造函数被调用!"<<endl; } A(const char*pUser,const char*pPass) { strcpy(m_Username,pUser); strcpy(m_Password,pPass); cout<<"有参构造函数被调用!"<<endl; } char* GetUsername() const { return(char*)m_Username; } char* GetPassword() const { return(char*)m_Password; } }; int _tmain(int argc, _TCHAR* argv[]) { A a1; //定义A的对象,调用默认构造函数 cout<<"用户名"<<a1.GetUsername()<<endl; A * pa = new A("VBCDE","MBEFG"); //定义A的对象,调用有参的构造函数 cout<<"用户名"<<pa->GetUsername()<<endl; delete pa; //释放pareturn 0; }
示例三 复制的构造函数按值调用
class A { private: char m_Username[128]; char m_Password[128]; public: A() { strcpy(m_Username,"MR"); strcpy(m_Password,"KJ"); cout<<"构造函数被调用!"<<endl; } A(const A &ra) { strcpy(m_Username,ra.m_Username); strcpy(m_Password,ra.m_Password); cout<<"复制构造函数被调用!"<<endl; } char* GetUsername() const { return(char*)m_Username; } char* GetPassword() const { return(char*)m_Password; } }; void OutputUser(A a) { cout<<a.GetUsername()<<endl; cout<<a.GetPassword()<<endl; } int _tmain(int argc, _TCHAR* argv[]) { A a; //调用构造函数 OutputUser(a); //调用复制构造函数 return 0; }
如果按引用调用如何呢?
我们只需更改
void OutputUser(A &a) //按引用调用 { cout<<a.GetUsername()<<endl; cout<<a.GetPassword()<<endl; }
则不会调用复制构造函数
从上分析可以得知,如果按值调用,则调用复制构造函数,如果按引用调用,则不会调用复制构造函数。
析构函数
析构函数是在对象释放时调用,进行对象的清理,那对象是何时被释放呢?如果对象是在栈中创建,则对象其作用域消失时释放如:
{
A a;
}
如果对象在堆中创建,则使用delete运算符作释放掉该对象。与构造函数类似,如果用户没有显示提供析构函数,则系统提供默认的析构函数。使用析构函数只需在函数名前加“~”符号。析构函数没有参数。析构函数也没有返回值。因此,析构函数不能够被重载。一个类只有一个析构函数。
示例 析构函数
//--------------------------------------------------------------------------- #pragma hdrstop #include <tchar.h> #include<iostream> using namespace std; //--------------------------------------------------------------------------- #pragma argsused class A { private: char m_Username[128]; char m_Password[128]; public: A() { strcpy(m_Username,"MR"); strcpy(m_Password,"KJ"); cout<<"构造函数被调用!"<<endl; } A(const A &ra) { strcpy(m_Username,ra.m_Username); strcpy(m_Password,ra.m_Password); cout<<"复制构造函数被调用!"<<endl; } ~A() { strcpy(m_Username,""); strcpy(m_Password,""); cout<<"析构函数被调用!"<<endl; } }; void OutputUser(A a) { cout<<"调用OutputUser函数"<<endl; } int _tmain(int argc, _TCHAR* argv[]) { A a; OutputUser(a); return 0; } //---------------------------------------------------------------------------
此程序一共调用了2次析构函数,当创建一个类A对象的时候,构造函数被调用,而调用OutputUser函数的时候,调用复制复制构造函数的对象拷贝到outputuser中,结果输出了复制构造函数被调用,而通过复制的构造的构造函数被调用结束是,析构函数被调用,而最后在mian函数中要结束时,A对象作用域也就消失,又会调用一次析构函数,所以析构函数会被调用2次。