一.先考虑在继承的时候基类与派生类的初始化顺序和一个类中的数据成员的初始化顺序
#include<iostream> using namespace std; class A { public: A(int x=0):m_data(x) { cout<<"Constructor A!!!\n"; } private: int m_data; }; class B { public: B(int x=0,int y=0):data(y) { cout<<"Constructor B!!!\n"; } private: int data; }; class C:public A,public B { public: C(int x=0,int y=0,int z=0):A(x),B(y),b(z),a(y) { cout<<"Constructor C!!!\n"; } private: int c_data; B b; A a; }; void main() { C b; }
顺序的判断就是一句话,在继承时候声明继承类的的顺序和在类中声明数据的顺序,这些顺序都是编译时候决定的,不会和初始化时候的顺序有关系
二.C++中钻石类的继承
下面就是一个钻石类,因为最base 类会在最低的继承类中存在两种从 derived 继承来的版本,这样就造成了数据的不准确
#include<iostream> using namespace std; class A { public: A(int x=0):m_data(x) { cout<<"constructor A\n"; } void show () { cout<<m_data<<"\n"; } private: int m_data; }; class B:virtual public A { public: B(int x=0):A(x) { cout<<"constructor B\n"; } void show() { show(); cout<<m_data<<"\n"; } private: }; class C:virtual public A { public: C(int x=0):A(x) { cout<<"constructor C\n"; } }; class D:public B,public C { public: D(int x=0):B(x),C(x) { cout<<"constructor D\n"; } }; void main() { D d(1); <span style="font-size:18px;">}</span>
所以虚基类的出现解决了这种出现两个不同的版本的基类数据,导致在调用时候还必须指定调用声明
#include<iostream> using namespace std; class A { public: A(int x=0):m_data(x) { cout<<"constructor A\n"; } virtual void show () { cout<<"A:: "<<m_data<<"\n"; } virtual A* Ret()//VC 6.0 不支持这种,vs 2008支持其实这个函数符合3同,返回值,函数名,参数相同 { cout<<"A:: Ret Fuction!!!\n"; return this; } virtual ~A()//在存在指针数据的类中,把析构函数设计成虚函数更能体现出价值 { cout<<"Destructor A!!!"; } private: int m_data; }; class B: public A { public: B(int x=0,int y=0):A(x),data(y) { cout<<"constructor B\n"; } void show() { cout<<"B:: "<<data<<"\n"; } B* Ret() { cout<<"B:: Ret Fuction!!!\n"; return this; } ~B() { cout<<"Destructor B!!!"; } private: int data; }; void main() { A a; B b(1,2); a=b; a.show(); a.Ret(); cout<<"\n\n"; //以下可以实现多态都是依靠赋值兼容规则借助指针和引用实现 A *ptr=&b; ptr->show(); ptr->show(); A &p=b; p.show(); p.Ret(); }
上边简单的实现了多态的一些性质,后边会继续讨论多态这次只是入门
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-12-07 22:39:54