just do it and waiting

直接初始化和拷贝初始化

2021-03-02


拷贝初始化底层是先调用构造函数创建一个临时变量,再将临时变量通过拷贝构造函数创建新变量。考虑如下过程

class A{
public:
    A() { cout << "default constructor" << endl; }
    A(const string& _str):str(_str) { cout << "constructor" << endl; }
    explicit A(const A& a) { cout << "copy constructor" << endl; }
    string str;
}

int main() {
    A a1;       // direct initialiazation
    A a2(string("hi"));  //  direct initialiazation
    A a3 = string("hi"); // error, string("hi") can't
                         // implicit convert to A
                         // (copy initialiazation)
    A a4 = a2;           // the same as above
                         // a2 can't implicit convert to A
                         // by call copy constructor
}

拷贝初始化发生情况

  1. = 定义变量时
string s1("hi");    // direct initialiazation
string s2 = s1;     // copy initialiazation
  1. 将一个对象作为实参传递给一个非引用类型的形参
void Foo(string s) {  
}
Foo(s1);            // copy initialiazation
  1. 从一个返回类型为非引用类型的函数返回一个对象
string Foo2(){
  string s("hi");
  return s;
}
Foo2();             // copy initialiazation
  1. 用花括号列表初始化一个数组中的元素或一个聚合类中的成员
// copy initialiazation
string strs[] = {"This", "is", "copy", "initialiazation"};

struct Data {
  int x;
  int y;
};

// copy initialiazation
Data dt = {0, 0};

三五法则

  1. 需要析构函数的类也需要拷贝和赋值操作

    需要息高函数一般是有内存要手动释放. 那么拷贝时也要手动管理这部分内存.

  2. 需要拷贝操作的类也需要赋值操作, 反之亦然

    考虑这样一个例子, 假设每个类具有独一无二的序号, 那么每次拷贝构造出一个新的类都需要一个新的序号, 同时, 类赋值的时候要避免将序号赋值出去. 但是, 这个类不需要自定义析构函数.