几乎每一个类都会用到构造、析构和赋值方法。
C++默认编写了哪些函数
- 拷贝构造函数
- 赋值操作符
- 析构函数
- 默认构造函数(如果你没有声明任何构造函数)
编译器默默添加的这些函数都是public inline
的。
默认构造函数,有两个职责
- 调用基类的构造函数
- 调用
non-static
成员变量的构造函数
析构函数,也有两个职责
- 调用基类的析构函数
- 调用
non-static
成员变量的析构函数
拷贝构造函数和赋值操作符
- 将源对象的每一个
non static
成员变量拷贝给目标对象
注意:
- 如果代码中未用到这些操作,编译器则不会创建对应的函数
- 编译器添加的析构函数是
non-virtual
的,除非基类自身声明有virtual
析构函数
如果我们写一个空的类
class Empty { };
即使我们的类什么方法都没有,下面这些操作也是合法的
Empty e1;//用到默认构造函数
Empty e2(e1);//用到拷贝构造函数
e2 = e1;//用到赋值操作符
因为,c++会默默的为你编写相关的函数
class Empty{
public:
Empty() {...}
Empty(const Empty& rhs) {...}
~Empty() {...}
Empty& operator=(const Empty& rhs) {...}
};
如果编译器不知道该怎么赋值
如果编译器不知道怎么赋值,将会拒绝为类自动添加赋值操作符
- 内含reference成员的类
- 内含const成员的类
- 基类将赋值操作符声明为private的类
template<class T>class NamedObject{
private:
std::string& nameValue;
const T objectValue;
};
NamedObject<int> s;
NamedOjbect<int> p;
p = s;
由于对引用的赋值和const的赋值都是非法的,编译器不知道该怎么生成赋值操作符,因此会拒绝自动添加赋值操作符
同样,如果基类将赋值操作符声明为private,继承类中的赋值操作符无法确定如何处理基数中的成员赋值问题,
同样无法自动添加赋值操作符。