拷贝构造函数
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, '.');//拷贝构造函数初始化
但在一下情况,也会隐式调用拷贝构造函数:
- 将对象作为实参传递。
- 返回一个对象(非引用)。
- 用花括号初始化数组中的元素或者一个聚合类的成员。
- 容器的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;
}
链接一个以前写过的:
https://www.cnblogs.com/hellozhangjz/p/12347628.html