派生类对象多次初始化同一基类数据成员问题 假设【例8.1】中,类Window、HScrollbar、VScrollbari都是从同一个基类Port 派生,即: class Port{/*...*; class Window:public Port{/*..* class HScrollbar:public Port{/*...*; class VScrollbar:public Port{/*...* class ScrollableWind:public Window,public HScrollbar,public VScrollbar {/*...*/) Port Port Port 祖先类 创建ScrollableWnd对象时, Port的构造函数通过3条不同 Window HScrollbar VScrollbar 父类 的路径,被调用了3次,从而 将显示端口初始化3次。即, 1个子类有3个同名祖先类, ScrollableWnd 子类 不符合实际! Scrollable Wnd派生树图 7
7 派生类对象多次初始化同一基类数据成员问题 假设【例8.1】中,类Window 、HScrollbar 、VScrollbar都是从同一个基类Port 派生,即: class Port{ /*…*/}; class Window:public Port{ /*…*/}; class HScrollbar:public Port{ /*…*/}; class VScrollbar:public Port{ /*…*/}; class ScrollableWind:public Window,public HScrollbar,public VScrollbar{/*…*/}; 创建ScrollableWnd对象时, Port的构造函数通过 3条不同 的路径,被调用了 3次,从而 将显示端口初始化 3次。即, 1个子类有 3个同名祖先类, 不符合实际! Port Port Port Window HScrollbar VScrollbar ScrollableWnd ScrollableWnd派生树图 祖先类 父类 子类
8.2虚基类 虚基类 Port 祖先类 如何实现:1个子类通 过3条不同的路径到达 Window HScrollbar VScrollbar 父类 同一个祖先类?即,创 建Scrollable Wnd对象 ScrollableWnd 子类 时,显示端口Port仅被 初始化1次? ScrollableWnd派生树和存储空间 class Window:virtual public Port{/*...*; class HScrollbar:public virtual Port{/*...*; virtual和派生方式可以互换位置 class VScrollbar:public virtual Port{/*...*); class Scrollable Wind:public Window,public HScrollbar,public VScrollbar (/*..* 上二页 下二页 8
8 8.2 虚基类 如何实现:1个子类通 过3条不同的路径到达 同一个祖先类?即,创 建ScrollableWnd对象 时,显示端口Port仅被 初始化1次? Port Window HScrollbar VScrollbar ScrollableWnd ? 祖先类 父类 子类 ScrollableWnd派生树和存储空间 class Window:virtual public Port{ /*…*/}; class HScrollbar:public virtual Port{ /*…*/}; class VScrollbar:public virtual Port{ /*…*/}; class ScrollableWind:public Window,public HScrollbar,public VScrollbar{/*…*/}; 虚基类 virtual和派生方式可以互换位置 上一页 下一页
虚基类使用说明 1.仅用于多继承,因为同一个类不能多次作为某个派生类的直 接基类,但可多次作为其间接基类,从而引起存储空间的浪 费和其他问题。 2.同一颗派生树中的同名虚基类,共享同一个存储空间;其构 造函数和析构函数仅执行1次;且构造函数尽可能最早执行, 而析构函数尽可能最晚执行。回上页 3.如果虚基类与基类同名,则它们将分别拥有各自的存储空 间,只有同名虚基类才共享存储空间,而同名基类则拥有各 自的存储空间。 4.虚基类和基类同名必然会导致二义性访问,编译程序会对这 种二义性访问提出警告。当出现这种情况时,要么将基类说 明为对象成员,要么将基类都说明为虚基类。分析【例83】 9
9 虚基类使用说明 1. 仅用于多继承,因为同一个类不能多次作为某个派生类的直 接基类,但可多次作为其间接基类,从而引起存储空间的浪 费和其他问题。 2. 同一颗派生树中的同名虚基类,共享同一个存储空间;其 构 造函数和析构函数仅执行 1 次,且构造函数尽可能最早执行, 而析构函数尽可能最晚执行。回上页 3. 如果虚基类与基类同名,则它们将分别拥有各自的存储空 间,只有同名虚基类才共享存储空间,而同名基类则拥有各 自的存储空间。 4. 虚基类和基类同名必然会导致二义性访问,编译程序会对这 种二义性访问提出警告。当出现这种情况时,要么将基类说 明为对象成员,要么将基类都说明为虚基类。分析【例8.3 】