C++ 赋值运算符和拷贝构造函数


拷贝构造函数

class Foo{
public:
    Foo();
    Foo(const Foo&); //自己定义的拷贝构造函数
};

如果不自己定义,编译器会自己合成一个默认拷贝构造函数

class Foo{
public:
    int a,b,c;
    Foo();
    Foo(const Foo&); //合成的拷贝构造函数
};
Foo::Foo(const Foo& f) : a(f.a), b(f.b), c(f.c) {}

拷贝构造函数总是用在初始化的时候,不要和赋值搞混。

string dots(10,'.');//构造函数初始化
string s(dots);		//构造函数初始化
string s2 = dots;	//拷贝构造函数初始化,不是赋值
string s3 = string(10, '.');//拷贝构造函数初始化

但在一下情况,也会隐式调用拷贝构造函数:

  1. 将对象作为实参传递。
  2. 返回一个对象(非引用)。
  3. 用花括号初始化数组中的元素或者一个聚合类的成员。
  4. 容器的push(), push_back()等就是拷贝初始化,而emplace_back()是直接初始化。

拷贝赋值运算符:“=”

class Foo{
public:
    Foo();
    Foo& operator=(const Foo&); //重载赋值运算符
};

如果不自己定义,编译器会自己合成一个默认拷贝赋值运算符

class Foo{
public:
    int a,b,c;
    Foo();
    Foo& operator=(const Foo&); //合成的拷贝构造函数
};
Foo& Foo::operator=(const Foo& f)
{
    a = f.a;
    b = f.b;
    c = f.c;
    return *this;
}

一般情况下,如果类需要自定义的析构函数,那么必定需要自定义赋值运算符和拷贝构造函数。

如果需要自定义赋值运算符(拷贝构造函数),那么必定需要自定义拷贝构造函数(赋值运算符),但不一定必须定义析构函数。

自定义赋值运算符要注意自赋值的情况

禁止拷贝、赋值

一些情况下类禁止拷贝,赋值,例如cin,cout。

class Foo
{
public:
    Foo(const Foo&) = delete;
    Foo& operator=(const Foo&) = delete;
}

链接一个以前写过的:

相关