包含表示has-a模式,<valarray>类

来源:互联网 发布:淘宝卖的衣服味道刺鼻 编辑:程序博客网 时间:2024/06/16 11:54

假如我们现在需要一个Student类,里面储存了学生的name和scores,一般提到name会想到用char数组,提到scores会想到用double型数组,但使用数组就会带来的一个长度不确定的问题,要是声明一个很大的数组,太浪费内存空间,要是在长度不够用的时候再改变长度,则又太繁琐。

这时候可以用C++自带的模板类,用string型变量储存name,用valarray储存scores。

对于valarray,声明语法如下:

valarray<int> v1;  //一个int型数组,size为0valarray<double> v2(8);  //一个double型数组,size为8valarray<int> v3(10,8);  //一个int型数组,size为8,每个值都为10double GPA[4]={3.0,3.6,3.8,4.0,2.9};valarray<double> v4(GPA,4);  //一个double型数组,size为4,取GPA数组的前四项给它赋值

valarray使用动态内存分配数组空间,<typename>声明初始化的数组类型。

声明语法乍看之下很像直接声明数组的语法,但声明数组是v[],这里是v(),它本质上是类的构造函数。

valarray有size,sum,max,min等基本方法可以让使用者了解数组的基本情况。


现在已经有了可以存放的name和scores的模板类,根据刚学的公有继承,一般会想到让Student类同时继承这两个模板类,C++支持这一点,但这里不行。因为公有继承表示的是一种is-a关系,即派生类本质上也是基类(apple是fruit),而这里需要的关系是Student类包含string,valarray类,这被成为has-a关系,具体实现方法为:

class Student{private:       string name;       valarray<double> scores;public:       ......};

has-a关系和is-a关系有很大的不同,has-a关系只获得类成员的实现不继承类成员的接口,要想对Student里的string对象name做出修改,需要调用string类的公有接口,例如name.size()调用name的size方法。

下面给出一段较完整的Student类定义:

typedef valarray<double> varrayDB;  //valarray<double>可以像int,double一样取别名class Student{private:       string name;  //这里只是声明,给下面的Student构造函数提供一个可以调用的类成员       varrayDB scores;public:       Student():name("NULL student"),scores(){}  //Student类要通过string和varrayDB调用他们的方法       explicit Student(int n):name("NULL student"),scores(n){}  //用explicit关键字修饰只需一个参数的构造函数,避免Student stu=5这种隐式转换       Student(const string& s,int n):name(s),scores(n){}       ~Student(){}};