1,没有虚继承的MI
#include <iostream> #include <string> using namespace std; /* MI(多重继承) 虚基类 */ /* MI继承图: test_base / \ / \ test1 test1_1 \ / \ / test2 */ class test_bae //基类 test_base { private: string str; public: test_bae(string str):str(str){} virtual void show() { cout << this->str << " (地址:" << this << ")\n"; } }; class test1:public test_bae //test_base的派生类 { private: int a; public: test1(string str, int a):test_bae(str),a(a){} virtual void show() { test_bae::show(); cout << "a: " << a << endl; } }; class test1_1:public test_bae //test_base的派生类 { private: double b; public: test1_1(string str, double b):test_bae(str),b(b){} virtual void show() { test_bae::show(); cout << "b: " << b << endl; } }; class test_2:public test1, public test1_1 //继承自test1和test1_1 { public: test_2(string str, int a, double b):test1(str,a),test1_1(str,b){} virtual void show() { test1::show(); test1_1::show(); } }; void main() { test_2 one("hello",1,2.2); one.show(); /* 输出结果: hello (地址:0018FC5C) a: 1 hello (地址:0018FC7C) b: 2.2 显然这个结果(输出两个不同地址重复的string)并不是我们想要的,问题出在哪里? 观察地址可以发现,程序运行时生成了两个基类(一个来自test1 一个来自test1_1), 所以才会有两个基类 解决办法 使用虚基类, 看下面代码 */ system("pause"); }
class test_bae //基类 test_base { private: string str; public: test_bae(string str):str(str){} virtual void show() { cout << this->str << " (地址:" << this << ")\n"; } }; class test1:public virtual test_bae //test_base的派生类 { private: int a; public: test1(string str, int a):test_bae(str),a(a){} virtual void show() { test_bae::show(); cout << "a: " << a << endl; } }; class test1_1: virtual public test_bae //test_base的派生类 { private: double b; public: test1_1(string str, double b):test_bae(str),b(b){} virtual void show() { test_bae::show(); cout << "b: " << b << endl; } }; class test_2:public test1, public test1_1 //继承自test1和test1_1 { public: test_2(string str, int a, double b):test_bae(str),test1(str,a),test1_1(str,b){} //这里有变动,必须显示的调用所有的基类的构造函数 virtual void show() { test1::show(); test1_1::show(); } }; void main() { test_2 one("hello",1,2.2); one.show(); /* 输出结果: hello (地址:004FF8CC) a: 1 hello (地址:004FF8CC) b: 2.2 显然现在两个地址一样了 证明只有一个基类了,解决办法就是虚继承 注意:虚继承 没法传递基类构造函数 所以必须显示的调用基类函数(参见上面代码的构造函数) 接下来还有一个问题就是基类被输出了两次,解决办法就是把 show 里面的数据分开,代码如下: */ system("pause"); }3,使用了虚继承的MI&分离了show数据
class test_bae //基类 test_base { private: string str; public: test_bae(string str):str(str){} virtual void show() { this->Date(); } protected: virtual void Date() const { cout << this->str << " (地址:" << this << ")\n"; } }; class test1:public virtual test_bae //test_base的派生类 { private: int a; public: test1(string str, int a):test_bae(str),a(a){} virtual void show() { test_bae::Date(); this->Date(); } protected: virtual void Date() const { cout << "a: " << a << endl; } }; class test1_1: virtual public test_bae //test_base的派生类 { private: double b; public: test1_1(string str, double b):test_bae(str),b(b){} virtual void show() { test_bae::Date(); this->Date(); } protected: virtual void Date() const { cout << "b: " << b << endl; } }; class test_2:public test1, public test1_1 //继承自test1和test1_1 { public: test_2(string str, int a, double b):test_bae(str),test1(str,a),test1_1(str,b){} //这里有变动,必须显示的调用所有的基类的构造函数 virtual void show() { test_bae::Date(); test1::Date(); test1_1::Date(); this->Date(); } protected: virtual void Date() const { } }; void main() { test_2 one("hello",1,2.2); one.show(); /* 输出结果: hello (地址:0018F930) a: 1 b: 2.2 完美!现在是我们想要的结果,具体改动就是 test_base 里面添加一个 保护函数 test_base::Date() test1 里面添加一个 保护函数 test1::Date() test1_1 里面添加一个 保护函数 test1_1::Date() Data 函数只包含本类的 要输出的数据, 然后show函数在把 各个Date 连接起来 !!over!! */ system("pause"); }