1.会默认生成的函数
需要这些函数的时候编译器才会默认生成这些函数,不需要(代码中没有相关操作)则编译器不生成相应的函数。
编译器默认生成的析构函数不是虚函数,除非基类中的析构函数时虚函数。
2.copy constructor
class NamedObject
{
public:
NamedObject(const char* name, const int& value)
: nameValue(name),
objectValue(value){};
~NamedObject(){};
private:
string nameValue;
int objectValue;
};
上面例子中的拷贝构造函数在执行时,对于string nameValue
,会调用string
的拷贝构造函数,而对于内置类型int
,则按比特进行拷贝。
3.copy assignment赋值运算符
只有当生出的代码合法且适当机会证明它有意义,编译器才会生出operator=。 这要如何理解呢?如果生出的代码不合法,编译器是不会生成operator=
的,那什么样的代码不合法呢?
template<typename T>
class NamedObject
{
public:
NamedObject(string& name, const T value)
: nameValue(name), objectValue(value){};
~NamedObject(){};
private:
string& nameValue;//注意是引用
const T objectValue;//注意是const
};
会发生什么事呢?
按照逻辑推理一下:假设编译器生成了operator=
,然后按照顺序对p中的成员变量挨个执行赋值操作,p中的nameValue
是个string
类型的引用,现在要对引用赋值!!!
引用在初始化之后就一直引用该变量,不能引用别的了。所以这里编译器就懵了,兄弟你到底要生成个啥样式儿的operator=
?于是乎编译器摊手说生不了,拒绝。
即:以下情况编译器不会生成默认的operator=
:
- 内含reference成员
- 内含const成员
- 基类中的copy assignment是私有的
4.如果不想让编译器生成operator=怎么办
如果不想让编译器生成,那就自己写一个。如果是不想有赋值操作呢?就是不想让同类的对象间可以a=b,那就需要上面列出的第三条了。
将基类中的copy assignment变为私有的!
在HomeForSale
中没有定义operator=
,那么如果代码中有a=b的操作,编译器就试图生成一个默认的operator=
,但是基类的operator=
是私有的,编译器就会拒绝生成并报错,这样就达到了不能进行赋值操作的目的。
使用=delete
任何函数都能delete,但是只有默认构造函数与拷贝构造函数使用=default。