文章目录
一、概念
1、拷贝构造
TClass C(A); // 这个时候会调用一次拷贝构造
2、赋值运算符
TClass C; // 这个时候会调用一次默认构造
C = A; // 这个时候会调用一次 '=' 赋值运算
3、引例
class TClass
{
public:
// 默认构造函数
TClass() {
printf("Default Constructor\n");
}
// 拷贝构造函数
TClass(const TClass& other) {
printf("Copy Constructor\n");
Copy(other);
}
// 赋值运算符重载
TClass& operator=(const TClass &other) {
printf("operator=\n");
Copy(other);
return *this;
}
// 析构函数
virtual ~TClass() {}
// 拷贝
void Copy(const TClass &other) {
data = other.data;
}
private:
int data;
};
TClass A, B; // 1
TClass C(A); // 2
TClass D = B; // 3
B = A; // 4
- 看到上面四行,分别调用的是什么构造函数呢?
- 思考一分钟 …
- 揭晓答案:
TClass A, B; // Default Constructor
TClass C(A); // Copy Constructor
TClass D = B; // Copy Constructor
B = A; // operator=
- 其中 第三行 是易错点,接下来我们把这些点总结一下;
二、知识点剖析
1、传参(非指针或引用)走拷贝构造
struct TClassDelegatorA {
TClassDelegatorA(TClass akTC) {
}
};
TClassDelegatorA AA(A);
Copy Constructor
- 参数是非引用的类对象实例,会默认走一次拷贝构造函数;
2、引用传参不走拷贝构造
struct TClassDelegatorB {
TClassDelegatorB(TClass& akTC) {
}
};
TClassDelegatorB BB(A);
- 无任何输出,因为引用相当于别名,传参时不需要拷贝构造函数;
3、类成员变量不初始化走默认构造
struct TClassDelegatorC {
TClass tc_;
TClassDelegatorC(TClass akTC) {
}
};
TClassDelegatorC CC(A);
Copy Constructor
Default Constructor
- 第一个输出是函数传参走的拷贝构造函数;
- 第二个输出是类成员 tc_ 自己的默认构造函数,TClassDelegatorC 类构造的时候会走一遍所有成员变量的构造函数;
4、类初始化列表走拷贝构造
struct TClassDelegatorD {
TClass tc_;
TClassDelegatorD(TClass akTC) : tc_(akTC) {
}
};
TClassDelegatorD DD(A);
Copy Constructor
Copy Constructor
- 第一个输出是函数传参走的拷贝构造函数;
- 第二个输出是类成员初始化列表里调用到的拷贝构造函数;
5、赋值不走拷贝构造,走’='运算符
struct TClassDelegatorE {
TClass tc_;
TClassDelegatorE(TClass akTC) {
tc_ = akTC;
}
};
TClassDelegatorE EE(A);
Copy Constructor
Default Constructor
operator=
- 第一个输出是函数传参走的拷贝构造函数;
- 第二个输出是类成员 tc_ 自己的默认构造函数,TClassDelegatorE 类构造的时候会走一遍所有成员变量的构造函数;
- 第三个输出是赋值是调用的赋值运算符;
6、初始化赋值走拷贝构造,不走’='运算符
struct TClassDelegatorF {
TClass tc_;
TClassDelegatorF(TClass akTC) {
TClass akTmpTC = akTC;
}
};
Copy Constructor
Default Constructor
Copy Constructor
- 第一个输出是函数传参走的拷贝构造函数;
- 第二个输出是类成员 tc_ 自己的默认构造函数,TClassDelegatorF 类构造的时候会走一遍所有成员变量的构造函数;
- 第三个输出是初始化 akTmpTC 调用的拷贝构造;