CPP_默认构造函数、复制构造与转移构造

1、默认构造

默认构造一般由编译器给你实现了,当然你也可以自己定义;

class student 
{
    private:
        int count;
    student();

};

student::student()
{
     count++;
}

2、复制构造

这个就有点好玩了,复制构造在什么时候会用到呢?

1.当你往函数中传递对象时(传递对象,而不是引用)
2.当你试图返回一个对象时
3.当你试图初始化一个对象

eg:
1.往函数传递对象
class student
{
     private:
           int count=1;
     public:
           student(const student &);
           void show();
};

student::student(const student & a)
{
     count=a.count;
     std::cout<<"calling Copy!"<<std::endl;
     a.show();
}

void student::show()
{
     std::cout<<count<<std::endl;
}

void show_build(student showstu){}
int main(){student a;show_build(a);return 0;}

在传递对象给show_build时发生拷贝。
2.当你试图返回一个对象时
 将show_build函数改为
 student show_build(student showstu)
 {
      student c=showstu;
      return c;
 }
 显然,这里发生两次构造,第一次复制构造发生在传参,第二次时在返回时,这里有一个问题,关于深层拷贝和浅层拷贝,这里是使用临时变量初始化另一个对象。
3.当你试图初始化一个对象
  class a;
  class b=a;(发生复制构造)

3.转移构造

观察2.2中的状况,当你return一个对象时(作用域在函数内,在函数结束时销毁),函数其实是返回了一个临时变量,这里其实有点浪费空间,转移构造就是使用相似的思想,当你return一个临时变量时,调用转移构造,将临时变量的内存作为新对象的内存。

  student::student(const  student && b)
  {

  }

4.关于深拷贝与浅拷贝

深拷贝通常发生在使用显式复制构造函数与赋值运算符中。

eg.

String(const char *ch=""):_str(new char[strlen(ch)+1])
{
     strcpy(_str,ch);
}
String(String & str):_str=NULL
{
    String tmp(str._str);
    _str=tmp._str;
}//显式复制构造函数

String & operator=(String & s)
{
     if(this!=s)
     {
        //this._str(new char[strlen(s._str)+1]);
        //strcpy(this._str,s._str);
        String tmp(s._str);
        swap(tmp._str,this._str);
        return *this;
     }
}

浅拷贝通常发生在默认拷贝构造函数中

注:拷贝构造函数有时会与赋值函数混淆,举个例子 String s;
String str=s;//拷贝构造相当于String str(s)
String str;
str=s;//赋值构造

怎么分辨呢?拷贝构造函数只在对象被创建时调用,而赋值构造则是对象已被创建后调用

panda

继续阅读此作者的更多文章