博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++面向对象程序设计的一些知识点(2)
阅读量:5109 次
发布时间:2019-06-13

本文共 9657 字,大约阅读时间需要 32 分钟。

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 
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_Root19 {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 RootBase32 {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:RootBase48 {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 Base61 {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 
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 
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 Base25 {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 Base44 {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 B263 {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 
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 Manager117 {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 << ",编号:" << no132 << ",级别:" << 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

 

转载于:https://www.cnblogs.com/lit10050528/p/3426410.html

你可能感兴趣的文章
洛谷 1449——后缀表达式(线性数据结构)
查看>>
Data truncation: Out of range value for column 'Quality' at row 1
查看>>
Dirichlet分布深入理解
查看>>
(转)Android之发送短信的两种方式
查看>>
字符串处理
查看>>
HtmlUnitDriver 网页内容动态抓取
查看>>
ad logon hour
查看>>
获得进程可执行文件的路径: GetModuleFileNameEx, GetProcessImageFileName, QueryFullProcessImageName...
查看>>
证件照(1寸2寸)拍摄处理知识汇总
查看>>
罗马数字与阿拉伯数字转换
查看>>
Eclipse 反编译之 JadClipse
查看>>
Python入门-函数
查看>>
[HDU5727]Necklace(二分图最大匹配,枚举)
查看>>
距离公式汇总以及Python实现
查看>>
设计模式之装饰者模式
查看>>
一道不知道哪里来的容斥题
查看>>
Blender Python UV 学习
查看>>
window添加右键菜单
查看>>
入手腾龙SP AF90mm MACRO
查看>>
Window7上搭建symfony开发环境(PEAR)
查看>>