C++中的多重继承(一)
2019-05-24 06:10:35来源:博客园 阅读 ()
1,C++ 中是否允许一个类继承自多个父类?
1,可以;
2,这种情况就是多重继承;
3,多重继承的表象就是一个类有多个父类;
4,这是 C++ 非常特别的一个特性,在其他的程序设计语言中比如 C#、Java、Object Pascal 中都只支持单重继承;
2,C++ 支持编写多重继承的代码:
1,一个子类可以拥有多个父类;
2,子类拥有所有父类的成员变量;
3,子类继承所有父类的成员函数;
4,子类对象可以当作任意父类对象使用;
3,多重继承的语法规则:
1,代码示例:
1 class Derived : public BaseA, public BaseB, public BaseC 2 { 3 // ... 4 };
2,多重继承的本质与单继承相同;
4,多重继承问题一编程实验:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class BaseA 7 { 8 int ma; 9 10 public: 11 BaseA(int a) 12 { 13 ma = a; 14 } 15 16 int getA() 17 { 18 return ma; 19 } 20 }; 21 22 class BaseB 23 { 24 int mb; 25 26 public: 27 BaseB(int b) 28 { 29 mb = b; 30 } 31 32 int getB() 33 { 34 return mb; 35 } 36 }; 37 38 class Derived : public BaseA, public BaseB 39 { 40 int mc; 41 42 public: 43 Derived(int a, int b, int c) : BaseA(a), BaseB(b) // 初始化列表中同时调用父类的构造函数; 44 { 45 mc = c; 46 } 47 48 int getC() 49 { 50 return mc; 51 } 52 53 void print() 54 { 55 cout << "ma = " << getA() << ", " 56 << "mb = " << getB() << ", " 57 << "mc = " << mc << endl; 58 } 59 }; 60 61 int main() 62 { 63 cout << "sizeof(Derived) = " << sizeof(Derived) << endl; // 12 64 65 Derived d(1, 2, 3); 66 67 d.print(); 68 69 cout << "d.getA() = " << d.getA() << endl; // 1 70 cout << "d.getB() = " << d.getB() << endl; // 2 71 cout << "d.getC() = " << d.getC() << endl; // 3 72 73 cout << endl; 74 75 BaseA* pa = &d; 76 BaseB* pb = &d; 77 78 cout << "pa->getA() = " << pa->getA() << endl; // 1 79 cout << "pb->getB() = " << pb->getB() << endl; // 2 80 81 cout << endl; 82 83 void* paa = pa; 84 void* pbb = pb; 85 86 87 if( paa == pbb ) 88 { 89 cout << "Pointer to the same object!" << endl; 90 } 91 else 92 { 93 cout << "Error" << endl; // 打印 Error; 94 } 95 96 cout << "pa = " << pa << endl; // 0xbfe7e304 97 cout << "pb = " << pb << endl; // 0xbfe7e308 98 cout << "paa = " << paa << endl; // 0xbfe7e304 99 cout << "pbb = " << pbb << endl; // 0xbf7e308 100 101 return 0; 102 }
5,通过多重继承得到的对象可能拥有“不同地址”:
1,解决方案:无;
2,多重继承成员变量排布:
1,指向同一个对象的不同位置;
2,不方便开发了,因为我们一般比较这两个指针是否相同来判断是否指向同一个对象;
3,这里两个地址值不同依然可能指向同一个对象,情况变得非常复杂;
6,多重继承可能产生冗余的成员:
1,Doctor 这个类有两个 m_name,两个 m_age;
7,多重继承问题二编程实验:
1,描述 本文6 中类图:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class People 7 { 8 string m_name; 9 int m_age; 10 public: 11 People(string name, int age) 12 { 13 m_name = name; 14 m_age = age; 15 } 16 void print() 17 { 18 cout << "Name = " << m_name << ", " 19 << "Age = " << m_age << endl; 20 } 21 }; 22 23 class Teacher : virtual public People 24 { 25 public: 26 Teacher(string name, int age) : People(name, age) 27 { 28 } 29 }; 30 31 class Student : virtual public People 32 { 33 public: 34 Student(string name, int age) : People(name, age) 35 { 36 } 37 }; 38 39 class Doctor : public Teacher, public Student 40 { 41 public: 42 Doctor(string name, int age) : Teacher(name, age + 1), Student(name, age), People(name, age) 43 { // 如果在这里没有调用 People(name, age),编译器会在这一样显示如下错误: 44 // error: no matching function for call to 'People::People()' 45 // note: candidates are: People::People(std::string, int) 这是在父类构造的一行; 46 } // note: People::People(const People&) ,这个编译器提供,在类最开始那一行; 47 }; 48 49 int main() 50 { 51 Doctor d("Delphi", 33); 52 53 d.print(); // 未有虚继承时,编译器显示:error: request for member 'print' is ambiguous 54 // error: candidates are: void People::print() 55 // error: void People::print() 56 /* 未有虚继承时,可以这样分作用域分辨符来继承 */ 57 d.Teacher::print(); // Name = Delphi, Age = 33; 58 d.Student::print(); // Name = Delphi, Age = 33; 59 60 return 0; 61 }
8,多重继承关系出现闭合时将产生数据冗余的问题:
1,解决方案:虚继承;
2,代码示例:
1 class People {}; 2 class Teacher : virtual public People {}; 3 class Student : virtual public People {}; 4 class Doctor : public Teacher, public Student {};
9,多重继承的问题二:
1,虚继承能够解决数据冗余问题;
2,中间层父类不再关心顶层父类的初始化;
1,规则不清晰;
2,当今的软件产品,动则几十万行代码,业务逻辑已经很复杂了,我们希望编程语言越简单越好,不希望几套标准,这样的话,只会造成生成效率的低下和致命的 bug;
3,工程中可能是很多层继承,这样找的很麻烦,可以几班解决;
3,最终子类必须直接调用顶层父类的构造函数;
10,问题:
1,当架构设计需要继承时,无法确定使用直接继承还是虚继承;
1,开发者感觉增加了开发时间;
2,架构设计时,无法知道开发者是否会多重继承;
3,都做成虚继承的时候,多重继承加虚继承太过复杂,影响效率和移植性(不同编译器可能有不同实现方式);
4,多重继承只适合学术研究,工程一般不使用;
11,小结:
1,C++ 支持多重继承的编程方式;
1,除了 C++ 支持多重继承,基本上其它语言并不支持;
2,多重继承容易带来问题:
1,可能出现“同一个对象的地址不同”的情况;
2,虚继承可以解决数据冗余的问题;
3,虚继承使得架构设计可能出现问题;
原文链接:https://www.cnblogs.com/dishengAndziyu/p/10916298.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:C++对象在继承情况下的内存布局
- C++ 转换函数搭配友元函数 2020-06-10
- C++ 自动转换和强制类型转换(用户自定义类类型) 2020-06-10
- C++ rand函数 2020-06-10
- C++ 友元函数 2020-06-10
- C++ 运算符重载 2020-06-10
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash