构造函数&拷贝构造函数&赋值构造函数

来源:互联网 发布:红酒网络推广 编辑:程序博客网 时间:2024/06/05 04:08

class和struct很大一个区别在于,c除了成员的访问控制权限,struct中的成员默认是public,而class中的field默认是private;class还有一个special的地方是它有构造函数:constructor。

构造函数是class中的一员,和成员变量、其他成员函数一起构成一个完整的class。

构造函数用来在memory中开辟一个内存空间,并返回一个类实例的引用。构造函数包括:初始化构造函数、拷贝构造函数、赋值构造函数。

初始化构造函数顾名思义就是用来创建一个类实例,并对它的成员进行初始化的。下面是个栗子:

class Data{   private:      int year;      int month;      int day;      bool isAfternoon;  public:      Data(int,int,int);      Data(const Data &data);      ~Data(void);      Print(void);};Data::Data(int x, int y, int z){      year = x;      month = y;      day = z;}

上面的Data(int,int,int)就是一个初始化构造函数,使用的时候可以这样:
Data today(2016,4,28);

这样我们就通过初始化构造函数创建了一个叫做today的Data对象,并对它的成员变量year、month、day进行了初始化。


接着我们来看拷贝构造函数。什么是拷贝构造函数?推断没错的话应该是去年4月底瑶哥电面的时候问过我的一个问题。拷贝构造函数目的也是创建一个新对象,开辟属于它的内存空间,返回它的一个reference。和初始化构造函数不同,它需要一个已经存在的实例来进行这个创建过程。继续上面的例子,假设有了上面创建的today,现在创建对象night:

Data night(today);

也可以这样:
Data night = today;
需要说的是,拷贝构造函数的拷贝是一种浅拷贝,这意味着上面创建的night和today引用的是同一块内存空间,如果对night中的成员变量进行了修改,那么也会同步到today。


然后是赋值构造函数。从使用上赋值构造函数应该是最简单的。但是从实现角度,因为它要用到运算符的重载就不简单廖。上面的Data的赋值构造函数的声明可以like this:

Data & operate = (const Data &data);

如果这个时候有一个tomorrow对象,用today对它进行赋值,那么将会调用赋值构造函数:

Data tomorrow(2016,4,29);tomorrow = today;


如果出现=,例如上面的tomorrow = night,调的是赋值构造函数还是拷贝构造函数?如果在进行=之前tomorrow已经创建完成了,比如上面的实现,这个时候就是调用的赋值构造函数。如果一边进行=,一边进行创建,就像Data tomorrow = night,那么就是调用的拷贝构造函数,为了增强代码的可读性,最好这么写:Data tomorrow(night);


最后来一道很常见的考察构造函数的笔试题:“实现一个String类,至少要能实现以下:构造函数,析构函数,拷贝构造函数,重载赋值操作符。”

来一个参考:

class String{  private:       char *mContent;//记录字符的内容  public:        String(const char *content);        ~String();        String(const String &string);        String& operate = (const String &string);};String::String(const char *content){   if(content==NULL){     this->mContent = new char[1];     this->mContent = '\0';     return;   }   int lenght = strlen(content);   this->mContent = new char[lenght+1];   strcpy(this->mContent, string);}String::String(const String &string){   int length = strlen(string.mContent);   this->mContent = new char[length+1];   strcpy(this->mContent, string.mContent);}String::String& operate = (const String &string){   if(string.mContent==NULL)this->mContent=String(string);   strcpy(this->mContent, string.mContent);}String::~String(){   delete this->mContent;}






0 0