- public继承是is-a的关系
- derived class作用域被嵌套在base class作用域内
- 不重新定义继承而来的缺省参数值,virtual函数动态绑定,而缺省参数值却是静态绑定
- 避免遮掩继承而来的名称,即使base classes和derived classes内的函数有不同的参数类型也适用,而且不论函数是virtual 或 non-virtual 一样适用
class Base{ private: int x; public: virtual void mf1()=0; virtual void mf1(int); virtual void mf2(); void mf3(); void mf3(double); ... }; class Derived:public Base{ public: virtual void mf1(); void mf3(); void mf4(); };
如果你继承base class并加上重载函数,而又希望重新定义或覆写其中一部分,那么你必须为那些原本会被遮掩的每个名称引入一个using声明式,否则某些你希望继承的名称会被遮掩Derived d; int x; ... d.mf1(); //没问题,调用Derived::mf1 d.mf1(x); //错误,因为Derived::mf1遮掩了Base::mf1 d.mf2(); //没问题,调用Base::mf2 d.mf3(); //没问题,调用Derived::mf3 d.mf3(x); //错误,因为Derived::mf3遮掩了Base::mf3
class Base{ private: int x; public: virtual void mf1()=0; virtual void mf1(int); virtual void mf2(); void mf3(); void mf3(double); ... }; class Derived:public Base{ public: using Base::mf1; //让Base class内名为mf1和mf3的所有东西在Derived作用域内都可见 using Base::mf3; virtual void mf1(); void mf3(); void mf4(); };
如果Derived唯一想继承mf1那个无参数版本,可以用private继承,用一个简单的转交函数Derived d; int x; ... d.mf1(); //没问题,调用Derived::mf1 d.mf1(x); //现在没问题了,调用Base::mf1 d.mf2(); //没问题,调用Base::mf2 d.mf3(); //没问题,调用Derived::mf3 d.mf3(x); //现在没问题了,调用Base::mf3
class Derived:private Base{ public: virtual void mf1() {Base::mf1();} };
- 绝不重新定义继承而来的non-virtual函数。non-virtual函数是静态绑定的,由于pB被声明为一个pointer-to-B,通过pB调用的non-virtual函数永远是B所定义的版本,即使pB指向一个类型为“B派生之class”的对象
D x; B* pB=&x; pB->mf(); //调用B::mf pD->mf(); //调用D::mf class B{ public; void mf(); }; class D ::public B { public; void mf(); }; ``` 当mf被调用,任何一个D对象都可能表现出B或D的行为:决定因素不再对象自身,而在于“指向该对象之指针”当初的声明类型 或者理解为public继承是is-a的关系,适用于B的每一件事也适用于D,如果重新定义non-virtual设计便出现矛盾
- private base class继承而来的所有成员,在derived class中都会变成private属性,纵使它们在base class中原本是protected或是public属性。private继承意味着根据某物实现出,如果class D private 继承class B,用意是为了采用class B内已经具备的某些特性,不是因为B对象和D对象存在任何观念上的关系
- 当base class是一个空类时(只含typedef或者static成员变量或者non-virtual函数时),选择private继承而不是复合,因为复合是base class会有一个字节大小然后会根据内存对齐进行调整,private继承不会增加derived class大小;或者当需要访问base class成员或者重写virtual函数时,采用private继承,否则尽量用复合
- 非必要尽量不使用virtual bases;如果必须使用virtual base class,尽可能避免在其中放置数据
Effective C++笔记 —— 第六章
最新推荐文章于 2021-03-17 00:44:50 发布