// 有时函数返回的拷贝构造,会被编译器优化掉
/* ------------------------------------------------------------------ */
// 拷贝构造一般遇到class A内有指针,则可以考虑自己实现,因为避免里面new了东西,浅拷贝导致俩指针一样,但delete了两次
// 拷贝赋值一般也是遇到class A内有指针new东西,考虑自己实现,避免错误
class A {
public:
int* x;
int y;
A (int t) { // 构造函数
x = new int (0);
y = t;
}
~A() {
}
A (const A& a) { // 拷贝构造函数
this->x = a.x;
this->y = a.y;
}
A& operator= (const A& a) { // 拷贝赋值运算符
this->x = a.x;
this->y = a.y;
return *this;
}
};
- 对象不存在,且没用别的对象来初始化,就是调用了构造函数。
- 对象不存在,且用别的对象来初始化,就是拷贝构造函数。
- 对象存在,用别的对象来给它赋值,就是拷贝赋值运算符。
A a;
A b(a); // 拷贝构造函数,创建对象+初始化
A b=a; // 拷贝构造函数,创建对象+初始化
/*********************************/
A a;
A b;
b=a; // 拷贝赋值运算符,对象存在+赋值
-
一个对象以值传递的方式传入函数体。
-
一个对象以值传递的方式从函数返回。
-
一个对象需要通过另一个对象进行初始化。
-
浅拷贝:如果复制的对象中引用了一个外部内容(例如分配在堆上的数据),那么在复制这个对象的时候,让新旧两个对象指向同一个外部内容,就是浅拷贝。(指针虽然复制了,但所指向的空间内容并没有复制,而是由两个对象共用)。
-
深拷贝:如果在复制这个对象的时候为新对象制作了外部对象的独立复制,就是深拷贝。
- C++11可以直接=delete。
- 如果不想写拷贝构造函数和赋值函数,又不允许别人使用编译器生成的缺省函数,可将拷贝构造函数和赋值函数声明为私有函数,不用写实现。
class A
{
private:
A(const A& a) = delete; //C++11禁用拷贝构造函数
A& operate=(const A& a) = delete; //C++11禁用赋值函数
}
/*****************************************************/
class A
{
private:
A(const A& a); //私有拷贝构造函数
A& operate=(const A& a); //私有赋值函数
}