C++面向对象程序设计的一些知识点(2)

1、C++中三种继承方式及派生类中访问控制规则

(1)、C++支持的三种继承方式是public、protected、private。C++允许一个类同时以不同的方式对不同的基类加以继承。

(2)、

 

不同继承方式下基类成员在派生类中的访问控制
继承方式 基类成员访问控制
public protected private
public public protected no access
protected protected protected no access
private private private

no access

注意:在派生类中,表中所述的访问控制“private”和“no access”存在很大的差别。对来自基类且在派生类中访问控制为“no access”的成员,

在派生类中是不可见的(自然,派生类的外部也不可见);对来自基类且在派生类中访问控制为“private”的子成员,在派生类内部可以访问它

们,但在派生类外部不可以访问它们。

2、派生类对象内存模型分析

(1)、程序运行时派生类对象或存在于函数栈中或存在于系统给程序分配的堆中,它是一段物理内存。

(2)、派生类与基类之间的关系是一种“is-a”的关系,否则在逻辑上必然造成混乱。

()

3、派生类对象的构造过程和析构过程

(1)、在继承方向上,先基类对象,后派生类子对象;在同一层次上,先包含类子对象,再本类子对象;如果在同一层次上存在多个包含类子

对象时,按照声明顺序来构造。

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class EmbededA_Root
 6 {
 7 public:
 8     EmbededA_Root()
 9     {
10         cout << "1_a:constructing embedded sub object A.\n";
11     }
12     ~EmbededA_Root()
13     {
14         cout << "1_a:destructing embedded sub object A.\n";
15     }
16 private:
17 };
18 class EmbededB_Root
19 {
20 public:
21     EmbededB_Root()
22     {
23         cout << "1_b:constructing embedded sub object B.\n";
24     }
25     ~EmbededB_Root()
26     {
27         cout << "1_b:destructing embedded sub object B.\n";
28     }
29 private:
30 };
31 class RootBase
32 {
33 public:
34     RootBase():embedA(), embedB()
35     {
36         cout << "1:constructing root base sub object.\n";
37     }
38     ~RootBase()
39     {
40         cout << "1:destructing root base sub object.\n";
41     }
42 private:
43     
44     EmbededB_Root embedB;
45     EmbededA_Root embedA;
46 };
47 class Base:RootBase
48 {
49 public:
50     Base()
51     {
52         cout << "2:constructing base sub object.\n";
53     }
54     ~Base()
55     {
56         cout << "2:destructing base sub object.\n";
57     }
58 private:
59 };
60 class Derived:public Base
61 {
62 public:
63     Derived()
64     {
65         cout << "3:constructing derived sub object.\n";
66     }
67     ~Derived()
68     {
69         cout << "3:destructing derived sub object.\n";
70     }
71 private:
72 };
73 
74 int main()
75 {
76     {
77         Derived d;
78     }
79     int c;
80     cin >> c;
81     return 0;
82 }
View Code

运行结果是:

如果将类RootBase中的embedA和embedB声明顺序换一下的话,则结果是:

4、跨类的同名成员

(1)、派生类属性会隐藏其基类的同名属性,此时区分它们的方法是加上作用域限定符,即“积累名::属性名”。

(2)、在非多态的情况下,派生类同名函数永远使基类同名函数隐藏起来(即使成员函数的特征表不同)。

5、基类对象与派生类对象之间的转换

(1)、用派生类对象给基类对象赋值或者用派生类初始化基类引用;此时是安全的,通常我们也应该重新编写赋值运算符的重载。

(2)、用基类对象给派生类对象赋值;此时是危险的,不应该这么做。

(3)、基类指针指向派生类对象地址;基类指针至少包含指针值和允许访问范围这样两个属性,而且此时基类指针允许访问的范围仅限于派生类对象子对象。

(4)、派生类指针指向基类对象;此时是危险的,不应该这么做。

(5)、C++提供的类型转换运算符。

6、多继承

(1)、非虚拟基类多继承;

  1 #include <iostream>
  2 
  3 using namespace std;
  4 
  5 class Base
  6 {
  7 public:
  8     Base(int a)
  9     {
 10         this->a = a;
 11         cout << "common base sub object being constructed.\n";
 12     }
 13     void show()
 14     {
 15         cout << a << endl;
 16     }
 17     ~Base()
 18     {
 19         cout << "deleting common base sub object.\n";
 20     }
 21 private:
 22     int a;
 23 };
 24 class B1:public Base
 25 {
 26 public:
 27     B1(int a, int b1):Base(a)
 28     {
 29         this->b1 = b1;
 30         cout << "base1 sub object being constructed.\n";
 31     }
 32     void showBase()
 33     {
 34         show();
 35     }
 36     ~B1()
 37     {
 38         cout << "deleting base1 sub object.\n";
 39     }
 40 private:
 41     int b1;
 42 };
 43 class B2:public Base
 44 {
 45 public:
 46     B2(int a, int b2):Base(a)
 47     {
 48         this->b2 = b2;
 49         cout << "base2 sub object being constructed.\n";
 50     }
 51     void showBase()
 52     {
 53         show();
 54     }
 55     ~B2()
 56     {
 57         cout << "deleting base2 sub object.\n";
 58     }
 59 private:
 60     int b2;
 61 };
 62 class D:public B2, public B1
 63 {
 64 public:
 65     D(int a1, int b1, int a2, int b2, int d):B1(a1, b1), B2(a2, b2)
 66     {
 67         this->d = d;
 68         cout << "derived sub object being constructed.\n";
 69     }
 70     void showB1Base()
 71     {
 72         B1::showBase();
 73     }
 74     void showB2Base()
 75     {
 76         B2::showBase();
 77     }
 78     ~D()
 79     {
 80         cout << "deleting derived sub object.\n";
 81     }
 82 private:
 83     int d;
 84 };
 85 
 86 int main()
 87 {
 88     {
 89         D d(11, 2, 12, 3, 4);
 90         d.B1::show();
 91         d.B2::show();
 92         d.B1::showBase();
 93         d.B2::showBase();
 94         d.showB1Base();
 95         d.showB2Base();
 96     }
 97     int c;
 98     cin >> c;
 99     return 0;
100 }
View Code

此时基类对象在派生类对象中占有一个独立的内存空间。

(2)、虚拟基类多继承;

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class Base
 6 {
 7 public:
 8     Base(int a)
 9     {
10         this->a = a;
11         cout << "common base sub object being constructed.\n";
12     }
13     void show()
14     {
15         cout << a << endl;
16     }
17     ~Base()
18     {
19         cout << "deleting common base sub object.\n";
20     }
21 private:
22     int a;
23 };
24 class B1:virtual public Base
25 {
26 public:
27     B1(int a, int b1):Base(a)
28     {
29         this->b1 = b1;
30         cout << "base1 sub object being constructed.\n";
31     }
32     void showBase()
33     {
34         show();
35     }
36     ~B1()
37     {
38         cout << "deleting base1 sub object.\n";
39     }
40 private:
41     int b1;
42 };
43 class B2:virtual public Base
44 {
45 public:
46     B2(int a, int b2):Base(a)
47     {
48         this->b2 = b2;
49         cout << "base2 sub object being constructed.\n";
50     }
51     void showBase()
52     {
53         show();
54     }
55     ~B2()
56     {
57         cout << "deleting base2 sub object.\n";
58     }
59 private:
60     int b2;
61 };
62 class D:public B1, public B2
63 {
64 public:
65     D(int a, int b1, int b2, int d):B1(a, b1), B2(a, b2), Base(a)
66     {
67         this->d = d;
68         cout << "derived sub object being cosntructed.\n";
69     }
70     void showB1Base()
71     {
72         B1::showBase();
73     }
74     void showB2Base()
75     {
76         B2::showBase();
77     }
78     ~D()
79     {
80         cout << "deleting derived sub object.\n";
81     }
82 
83 private:
84     int d;
85 };
86 
87 int main()
88 {
89     {
90         D d(11, 2, 3, 4);
91 
92         d.showB1Base();
93         d.showB2Base();
94     }
95     int c;
96     cin >> c;
97     return 0;
98 }
View Code

此时基类子对象只包含一个。
7、继承综合应用实例

类关系UML图如图:

代码:

  1 #include <iostream>
  2 
  3 using namespace std;
  4 
  5 class Employee
  6 {
  7 public:
  8     Employee(char *name)
  9     {
 10         no = companyEmployee++;
 11         grade = 1;
 12         pName = new char[strlen(name) + 1];
 13         strcpy(pName, name);
 14         totalPay = 0.0;
 15     }
 16     ~Employee()
 17     {
 18         delete [] pName;
 19     }
 20 public:
 21     void pay(){}
 22     void promote(int increment)
 23     {
 24         grade += increment;
 25     }
 26     void displayInfo(){}
 27 protected:
 28     char *pName;
 29     int no;
 30     int grade;
 31     double totalPay;
 32     static int companyEmployee;
 33 private:
 34 };
 35 int Employee::companyEmployee = 100; // 静态变量初始化
 36 
 37 class Technician:public Employee
 38 {
 39 public:
 40     Technician(char *name, int workHours = 0):Employee(name)
 41     {
 42         rate = 100; // 100元/小时
 43         this->workHours = workHours;
 44     }
 45     void setWorkhours(int workHours)
 46     {
 47         this->workHours = workHours;
 48     }
 49     void pay()
 50     {
 51         totalPay = workHours*rate;
 52     }
 53     void displayInfo()
 54     {
 55         promote(2);
 56         cout << "兼职技术人员:" << pName << ",编号:" << no 
 57             << ",级别:" << grade << ",已付本月工资:" 
 58             << totalPay << endl;
 59     }
 60 private:
 61     double rate;
 62     int workHours;
 63 };
 64 class SaleMan:virtual public Employee
 65 {
 66 public:
 67     SaleMan(char *name, int sales = 0):Employee(name)
 68     {
 69         ratio = 0.004;
 70         this->sales = sales;
 71     }
 72     void setSales(double sales)
 73     {
 74         this->sales = sales;
 75     }
 76     void pay()
 77     {
 78         totalPay = sales*ratio;
 79     }
 80     void displayInfo()
 81     {
 82         promote(2);
 83         cout << "推销员:" << pName << ",编号:" << no 
 84             << ",级别:" << grade << ",已付本月工资:" 
 85             << totalPay << endl;
 86     }
 87 protected:
 88     double sales;
 89     double ratio;
 90 };
 91 class Manager:virtual public Employee
 92 {
 93 public:
 94     Manager(char *name, int monthlyPay = 6000):Employee(name)
 95     {
 96         this->monthlyPay = monthlyPay;
 97     }
 98     void setMonthlyPay(double monthlyPay)
 99     {
100         this->monthlyPay = monthlyPay;
101     }
102     void pay()
103     {
104         totalPay = monthlyPay;
105     }
106     void displayInfo()
107     {
108         promote(3);
109         cout << "经理:" << pName << ",编号:" << no 
110             << ",级别:" << grade << ",已付本月工资:" 
111             << totalPay << endl;
112     }
113 protected:
114     double monthlyPay;
115 };
116 class SaleManager:public SaleMan, public Manager
117 {
118 public:
119     SaleManager(char *name):SaleMan(name), Manager(name), Employee(name)
120     {
121         monthlyPay = 4000;
122         ratio = 0.002;
123     }
124     void pay()
125     {
126         totalPay = monthlyPay + sales*ratio;
127     }
128     void displayInfo()
129     {
130         promote(2);
131         cout << "销售经理:" << pName << ",编号:" << no
132             << ",级别:" << grade << ",已付本月工资:" 
133             << totalPay << endl;
134     }
135 private:
136 };
137 
138 int main()
139 {
140     Technician t("zhang san");
141     t.setWorkhours(100);
142     t.pay();
143     t.displayInfo();
144 
145     SaleManager sm("li si");
146     sm.setMonthlyPay(7000);
147     sm.setSales(1000);
148     sm.pay();
149     sm.displayInfo();
150     int c;
151     cin >> c;
152     return 0;
153 }
View Code

 

posted @ 2013-11-16 09:49  冷冰若水  阅读(672)  评论(2编辑  收藏  举报