第15章 面向对象程序设计
1. 构造基类和派生类。
其中A类是基类,B类是派生类。派生类的构造函数必须重新写过,不能继承。(因为毕竟两个类的类名都不一样,不可能构造函数继承)只继承其他的成员函数和成员变量。
派生类可以覆盖基类的虚函数,但是也可以选择不覆盖(即直接使用父类的函数版本)比例A类的print_1()虚函数就没有被覆盖。
基类的静态成员:如果基类有一个静态成员,那么基类和所有派生类都共同拥有这仅有的一个静态成员。


<??http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+IDwvcD4KPHA+Mi4gICAgu/nA4LXE0Om6r8r9xKzIz8q1ss7X7rrD0+vFycn6wOC1xNDpuq/K/cSsyM/KtbLO0rvWwqGjPC9wPgo8cD7S8s6qyOe5+82ouf27+cDgtcTS/dPDu/LWuNXrtffTw7qvyv2jrNTyvavKudPDu/nA4LXExKzIz8q1ss6w5rG+o6y1q8rHuMO6r8r9tcTKtc/Wyse2r8yssPO2qLXEo6y8tL/JxNzKx7v5wOC1xLqvyv3Ssr/JxNzKx8XJyfrA4LXEuq/K/aGjPC9wPgo8cD48aW1nIHNyYz0="https://www.cppentry.com/upload_files/article/49/1_0bxaz__.png" alt="\">

3. 派生类可以改变基类中成员的访问权限。
但是仅限于那些派生类可访问的基类成员。
使用using声明即可。

4. 派生类中与基类的同名成员将隐藏基类的该成员。

5. 在当前派生类中可以访问当前派生类的基类的protected成员,但是不可以访问别的基类或派生类的成员。

6. 除了重新定义虚函数外,派生类的成员一定不要和基类的成员同名。且一定要在派生类重新定义的虚函数前面加上virtual关键字(就算你不加,C++也默认该函数为虚函数,但是为了用该派生类的”客户”看的清晰,一定要加上)
如果基类有虚函数 virtual void p(); 的话,那么派生类如果定义一个函数void p(); 由于该函数与基类的虚函数同名且调用形式相同,所以void p()也是虚函数。强烈建议在派生类void p()前中加上virtual关键字。
如果派生类中的函数是 void p(int x=1); 这样的话,那么这个p函数不是虚函数且掩盖了基类的虚函数名p()。

我们依次分析上述4个调用:
首先是第一个pa->p(),此时pa=&b。因为pa是一个A类指针,所以编译器在类A中寻找p函数,但是它发现p函数是一个virtual的,所以动态绑定后调用的是B类的 virtual p()函数,但是B类的virtual p()使用的是A类的默认实现,所以这里最终调用的还是A::p()函数。
第二个pa->p()类似于第一个,也是虚函数调用,pa绑定的是&a,所以调用的是A::p()这个虚函数。
第三个b.p(),由于b是一个对象,所以p函数静态绑定,所以调用的是b::p(int x=1) 这个函数。
第四个a.p(),静态绑定,调用a::p()函数。
7. 用于多态的基类的析构函数一定要是虚函数。

因为如果基类的析构函数不是virtual的,delete 一个基类指针只会调用基类的析构函数,不会调用子类的析构函数(就算该指针是子类的指针).
