知识杂货铺

不卖切糕

View on GitHub
15 April 2019 11:22

《王道程序员求职宝典》笔记 - 第8章 类

by 宋强

成员初始化列表

成员初始化列表跟在构造函数的形参表之后,以冒号开始,为每一个成员给出初值,形如:

class A{
private:
        int i;
        int j;
public:
        A(): j(0), i(j+2){}
};

构造函数初始化函数顺序按照参数定义顺序,而不是初始化列表顺序,也就是说这个示例的情况下i仍然先被初始化之后j才被初始化,所以i被初始化成一个垃圾值而j被初始化成0。

必须在成员初始化列表中初始化的类型

复制构造函数(拷贝构造函数)

定义:只有单个形参,而且该形参是对本类类型对象的引用的函数。并且通常用const修饰。

如果复制构造函数不用引用,会变成值传递,值传递会导致参数的传递过程中会构造,而且仍然调用的是拷贝构造函数,就会导致拷贝构造函数调用拷贝构造函数,vs和gcc中都会编译出错。

使用形式:

string book1("123456789");
string book2 = book1;
string book3(book1);  //这两个分别代表两种拷贝构造的使用方式。

只有在初始化时才是复制构造函数,否则不是,

比如:

string book1("123456789");
string book2;
book_2 = book1;

就不属于拷贝构造,主要是他不属于构造。

函数形参被赋值也是调用的拷贝构造 P141,例1

初始化顺序容器的元素时,编译器会使用默认构造函数构造第一个类,之后使用拷贝构造函数构造剩下的类。

例如:

vector<string> svec(5);

深复制与浅复制 浅复制与深复制的差别在于复制完所有类的内容之后是否复制类所引用的对象,深复制复制,而浅复制不复制类所引用的对象,容易在创建和释放对象的过程中造成运行时错误。

析构函数

编译器将自动构造的一个析构函数,叫做‘合成析构函数’调用所有非static变量的析构函数,顺序为声明顺序的逆序。

无论类是否定义了自己的析构函数,编译器都会定义一个析构函数,如果类定义了,那么编译器定义的析构函数将在类自己的析构函数之后执行。

如果析构函数不是虚函数,那么基类指针指向子类对象时执行析构函数会调用基类析构函数,造成潜在的资源没有释放。

构造函数与析构函数的调用顺序

单继承情况下

派生类的构造函数需要在成员初始化列表中使用基类的构造函数初始化继承的基类对象,如果没有的话系统会调用默认的基类构造函数。

派生类的析构函数执行时会先调用派生类的析构函数,之后调用基类的析构函数(派生类中无须显式调用基类析构函数)。

P144 例1与例2 这种题的关键点在于构造顺序与析构顺序,按照这两个顺序一个一个推就能够推出来。

构造顺序:

析构顺序:

还有就是所有具有实例的对象依照被构造的顺序写在纸上,防止忘记构造或者析构哪一个实例。

多继承情况下

此时派生类会依次调用各个基类的构造函数,并且调用顺序取决于基类在类派生列表中的顺序,而不是构造参数列表的顺序。

操作符重载

形式:名字为operator后跟着所定义的操作符的符号,如:

operator +(){}

参数的书目取决于操作符是几元操作符,还取决于是否是成员函数,如果是成员函数的话在最开始多一个this指针,但是是隐式声明的。

可重载操作符表:

+ - * / % ^
& | ~ ! , =
< > <= >= ++ --
« » == != && ||
+= -= /= %= ^= &=
|= *= «= »= [] ()
-> ->* New new[] delete delete[]

不可重载的操作符:

:: * . ?:

带’.’的都不能重载

’=’赋值操作符重载

赋值操作符重载的问题

复制构造函数与赋值运算符的区别

构造函数、拷贝构造函数、析构函数和赋值重载函数都不可以被继承。

c++中的空类默认产生的成员函数 构造函数、复制构造函数、析构函数、赋值运算符重载函数、取址运算符重载函数和const取址运算符重载函数。

‘«’输出操作符重载

‘operator new’和’operator delete’的重载

c++中new的执行过程实际为:

  1. 调用名为’operator new’的标准库函数,分配足够大小空间。
  2. 运行构造函数,将内容放在新空间中。
  3. 将分配空间的首地址返回。

delete类似:

  1. 调用析构函数。
  2. 调用’operator delete’释放内存。

限制用户使用堆空间和栈空间 将operator new设为私有禁止用户申请堆空间,通过将对象的构造函数设为私有阻止对象使用栈空间。(但是函数调用不是还会使用吗

成员函数的重载、覆盖与隐藏

成员函数的重载

成员函数重载特征:

成员函数的覆盖

覆盖是指子类类型函数覆盖了积累的虚函数,要求如下:

成员函数的隐藏

隐藏就是子类中的方法覆盖了基类中的方法,导致基类中的方法不可见的请款。

这个分为两种情况:

基类子类中两个函数名字且参数列表相同,且基类不是虚函数 子类会覆盖父类的方法,若基类是虚函数就变成了覆盖了。

基类子类中两个函数名字相同但参数列表不同 此时无论基类中的方法是不是虚函数都会被隐藏。

习题

3

复制构造函数也属于构造函数?应该是调用了一次构造函数9次复制构造函数,或者是数组不属于顺序容器? (编程试一下

tags: c++ - 笔试