【C++ Primer】第十四章 C++中的代码重用
序:C++的一个主要目标是促进代码重用,其中包含公有继承、包含、使用私有或保护继承
一,包含对象成员的类
1)valarray类简介 #include <valarray>
作用:处理数值,支持数值中所有元素的值相加,找最大值,最小值
用法:vallarray <int> a; //数组 a size=0
vallarray <double> b(10); //数组 b size=10
vallarray <double> c(10,8); //数组 c size=8 每个元素设置为 10
int s={2,3,4,5,6}; vallarray <double> d(s,3); //数组d 取s的前三个元素
2)student 类设计
1)typedef:用来声明自定义数据类型,配合各种原有数据类型来达到简化编程的目的的类型定义关键字。
typedef double double_a; //为已知类型 double起别名 double_a
typedef struct node{
char *name;
int age;
} *Node;
typedef valarray<double> ArrayDb;//定义了一个double数组 的别名
2)explicit : 关闭构造函数的隐式转换
explicit student(int n):name("NULLy"),scores(n){};
如果 student dod("xiaotian",10);//定义对象 名字为“xiaotian" 数组有5个元素
dod=5;//重新定义dod对象 名字为空,数组有5个元素
如果没有explicit 则调用student(5); 将5转化为一个临时student 对象
二,私有继承:has-a关系
1)class student : private string, private valarray<double>
不同种类的继承
特征 | 公有继承 | 保护继承 | 私有继承 |
共有成员变成 | 派生类的公有成员 | 派生类的保护成员 | 派生类的私有成员 |
保护成员变成 | 派生类的保护成员 | 派生类的保护成员 | 派生类的私有成员 |
私有成员变成 | 派生类的私有成员 | 派生类的私有成员 | 派生类的私有成员 |
能否隐式向上转换 | 是 | 是 | 是 |
使用using 重新定义访问权限,让私有继承中的方法也可以调用
class student :private string,private valarray<double>
{
public:
using std::valarray::mix; //using 声明只使用 成员名,没有圆括号
using std::valarray::min;
}
三,多重继承
1)singer类和waiter类都继承了一个worker组件,如果新建一个类singerwaiter,
class singerwaiter :public singer,public waiter{};
则singerwaiter包含两个worker组件,这将引起问题。例如,通常可以将派生类的对象的地址赋给基类指针但是现在回出现二义性。
singerwaiter ed;
worker *pw = &ed;//这 会出现二义性
解决办法:
1>worker *pw=(waiter *)&ed;
worker *pw=(singer *)&ed;
2>虚基类
class singer:virtual public worker{};
class waiter:public virtual worker{};
这时 class singerwaiter:public singer,public worker;
2)C++在基类是虚拟的时候,禁止信息通过中间类自动传递给基类
3)singerwaiter ss; ss.show();//引起二义性
ss.singer::show();//解决问题
四,类模板
1)template <class Type> //template 告诉编译器,将要定义一个模板。class 是类型名,Type 是该变量名
2)简单的模板使用
说明:1)模板代码不能修改参数值,不能使用参数地址。所以不能使用n++和&n这种表达式
2)递归使用模板:Array<Array<int , 5>,10> a;//包含10个元素的数组,每个元素是包含5个元素的数组
int a[10][5]; //含有十行,每行包含5个元素
3)使用多个参数:template <class T1, class T2> //声明
class pa
{
T1 a;
T2 b;
};
pa<string ,int>("tianshuai",1);
复习题:虚基类与非虚基类之间的区别
如果两个继承路线有相同的祖先,则类中包含两个祖先的拷贝,而将基类设置成虚的则可以避免这种情况。