虚基类菱形派生关系

Posted satellite&

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了虚基类菱形派生关系相关的知识,希望对你有一定的参考价值。

一、实验目的:

1、掌握通过继承机制派生出新类的方法

2、掌握基类成员在不同派生方式下访问权限的变化

3、了解虚基类的用法

二、实验内容  

1、给出一段有错误的程序,分析访问属性。上机调试,使之能正确运行并得到正确结果。

2、分别定义Person类、Employee类、Student类以及在职研究生类PartTime_Graduate_Student,并且画出相应的继承层次图。

三、UML类图

 

 

 

  1 #ifndef _PERSON_H
  2 #define _PERSON_H
  3 
  4 #include<string>
  5 using namespace std;
  6 
  7 class Person
  8 {
  9 private:
 10     string name;
 11     char sex;
 12     int age;
 13 public:
 14     Person();
 15     Person(string iname,char isex,int iage);
 16     void showName();
 17     void showSex();
 18     void showAge();
 19 };
 20 #endif
 21 
 22 //person.cpp
 23 #include "person.h"
 24 #include <iostream>
 25 #include<string>
 26 
 27 using namespace std;
 28 Person::Person()
 29 {
 30     cout<<"name:";
 31     cin>>name;
 32     cout<<"sex:";
 33     cin>>sex;
 34     cout<<"age:";
 35     cin>>age;
 36     cout<<"construct a Person."<<endl;
 37 }
 38 Person::Person(string iname,char isex,int iage):name(iname),sex(isex),age(iage)
 39 {
 40     cout<<"iconstruct a Person."<<endl;
 41 }
 42 void Person::showName(){cout<<"name: "<<name<<endl;}
 43 void Person::showSex(){cout<<"sex: "<<sex<<endl;}
 44 void Person::showAge(){cout<<"age: "<<age<<endl;}
 45 
 46 
 47 //employee.h
 48 #include "person.h"
 49 
 50 class Employee:virtual public Person
 51 {
 52 private:
 53     string pos;//职务
 54     double empnum;//员工号
 55 public:
 56     Employee();
 57     Employee(string iname,char isex,int iage,string ipos,double iempnum);
 58     void showPos();
 59     void showEmpnum();
 60     void showEmp();
 61 };
 62 
 63 //employee.cpp
 64 #include "employee.h"
 65 #include <iostream>
 66 #include<string>
 67 
 68 using namespace std;
 69 
 70 Employee::Employee()
 71 {
 72     cout<<"position:";
 73     cin>>pos;
 74     cout<<"empnum:";
 75     cin>>empnum;
 76     cout<<"construct an Employee."<<endl;
 77 }
 78 Employee::Employee(string iname,char isex,int iage,string ipos,double iempnum):Person(iname,isex,iage),pos(ipos),empnum(iempnum)
 79 {
 80     cout<<"iconstruct an Employee."<<endl;
 81 }
 82 void Employee::showPos(){cout<<"position: "<<pos<<endl;}
 83 void Employee::showEmpnum(){cout<<"employee number: "<<empnum<<endl;}
 84 void Employee::showEmp()
 85 {
 86     showName();
 87     showSex();
 88     showAge();
 89     showPos();
 90     showEmpnum();
 91 }
 92 
 93 //student.h
 94 #include "person.h"
 95 
 96 class Student:virtual public Person
 97 {
 98 private:
 99     string maj;//专业
100     double stunum;//学号
101 public:
102     Student();
103     Student(string iname,char isex,int iage,string imaj,double istunum);
104     void showStunum();
105     void showMaj();
106     void showStu();
107 };
108 
109 //student.cpp
110 #include "student.h"
111 #include <iostream>
112 #include<string>
113 
114 using namespace std;
115 
116 Student::Student()
117 {
118     cout<<"major:";
119     cin>>maj;
120     cout<<"Student_number:";
121     cin>>stunum;
122     cout<<"construct a Student."<<endl;
123 }
124 Student::Student(string iname,char isex,int iage,string imaj,double istunum):Person(iname,isex,iage),maj(imaj),stunum(istunum)
125 {
126     cout<<"iconstruct a Student."<<endl;
127 }
128 void Student::showStunum(){cout<<"student number: "<<stunum<<endl;}
129 void Student::showMaj(){cout<<"major: "<<maj<<endl;}
130 void Student::showStu()
131 {
132     showName();
133     showSex();
134     showAge();
135     showMaj();
136     showStunum();
137 }
138 
139 //PartTime_Graduate_Student.h
140 #include "employee.h"
141 #include "student.h"
142 
143 class PartTime_Graduate_Student:public Employee,public Student
144 {
145 private:
146     string graduate_school;//graduate_school
147 public:
148     PartTime_Graduate_Student();
149     PartTime_Graduate_Student(const string &iname,char isex,int iage,const string &ipos,double iempnum,const string &imaj,double istunum,const string &igs);
150     void showSchool();
151     void showAll();
152 };
153 
154 //PartTime_Graduate_Student.cpp
155 #include "PartTime_Graduate_Student.h"
156 #include <iostream>
157 #include<string>
158 
159 using namespace std;
160 
161 PartTime_Graduate_Student::PartTime_Graduate_Student()
162 {
163     cout<<"graduate school:";
164     cin>>graduate_school;
165     cout<<"construct a PartTime_Graduate_Student."<<endl;
166 }
167 PartTime_Graduate_Student::PartTime_Graduate_Student(const string &iname,char isex,int iage,const string &ipos,double iempnum,const string &imaj,double istunum,const string &igs):Person(iname,isex,iage),Employee(iname,isex,iage,ipos,iempnum),Student(iname,isex,iage,imaj,istunum),graduate_school(igs)
168 {
169     cout<<"iconstruct a PartTime_Graduate_Student."<<endl;
170 }
171 void PartTime_Graduate_Student::showSchool(){cout<<"graduate school: "<<graduate_school<<endl;}
172 void PartTime_Graduate_Student::showAll()
173 {
174     showName();
175     showSex();
176     showAge();
177     showPos();
178     showEmpnum();
179     showMaj();
180     showStunum();
181     showSchool();
182 }
183 
184 //main.cpp
185 #include "PartTime_Graduate_Student.h"
186 #include <iostream>
187 #include<string>
188 
189 using namespace std;
190 
191 int main()
192 {
193     PartTime_Graduate_Student pa("zzy",\'f\',18,"manager",2001,"computer science",2101,"ouc");
194     pa.showAll();
195     PartTime_Graduate_Student pb;
196     pb.showAll();
197     return 0;
198 }

 

 

1.virtual继承: 为了解决多重继承中有共同的基类(菱形继承)时的问题. 需要使用virtual继承的方式.

2.出现报错“error: expected primary-expression before XXX”(pgs类中的有参构造函数)因为XXX变量的调用时,前方多加了变量类型关键字,删掉即可。

3.warning "will be initialized after [-Wreorder](student类中stunum:double和major:string出现和初始化的顺序不对应)原因:构造函数时,初始化成员变量的顺序要与类声明中的变量顺序相对应,若不对应,则出现如此警告。解决方法就是按照顺序进行初始化,或者调整类中数据成员(变量)出现的顺序。student类中stunum:double先出现,major:string后出现,但在初始化时却先major后stunum,故出错。调整major和stunum在类中定义的顺序后解决。

4.no matching function for call to `xushu::set(xushu)\'(主函数中用psg创建有参对象pa时,没有写igs对应的实参)编译器没有找到签名为 xushu::set(xushu)的函数。要么是函数写错了,要么是调用的时候写错了。

 

 1 #include<iostream>
 2 using namespace std;//修改
 3 
 4 class X{
 5 public:
 6     X(int x){a=x;}
 7     void showX(){cout<<"a="<<a<<endl;}
 8 private:
 9     int a;
10 };
11 
12 class Y: private X{
13 public:
14     Y(int x,int y):X(x){b=y;}//修改
15     void showY( )
16     {
17         showX();//修改
18         cout<<"b="<<b<<endl;
19     }
20     void showX()//修改
21     {
22         return X::showX();
23     }
24 private:
25     int b;
26 };
27 
28 class Z: public Y{
29 public:
30     Z(int x, int y, int z):Y(x,y){ c=z; }
31     void showZ()
32     {
33         showY();//修改
34         cout<<"c="<<c<<endl;
35     }
36 private:
37     int c;
38 };
39 
40 int main( )
41 {
42     Z obj(10, 20, 30);
43     obj.showX( );
44     obj.showY( );
45     obj.showZ( );
46 }
47 /*
48 
49 Requirement:
50 
51 *Y is a private subclass of X.
52 
53 *Z is a public subclass of Y.
54 
55 *a, b, and c are encapsulated data members.
56 
57 *Do not change the interface in function main( ).
58 
59 *Output:
60 
61 a=10
62 
63 a=10
64 
65 b=20
66 
67 a=10
68 
69 b=20
70 
71 c=30
72 */

 

以上是关于虚基类菱形派生关系的主要内容,如果未能解决你的问题,请参考以下文章

理解虚基类多重继承的问题

理解虚基类多重继承的问题

C++ ——虚继承时的构造函数

C++ ——虚继承时的构造函数

多重继承,虚基类

C++学习20 虚基类详解