C++Primer Plus C++中的代码重用:包含对象成员的类14.1

系列文章目录

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:包含对象成员的类14.1


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

提示:这里可以添加本文要记录的大概内容:
包含对象成员的类14.1

首先介绍包含对象成员的类。有一些类(如string类和第16章将介绍的标准 C++类模板)为表示类中的组件提供了方便的途径。下面来看一个具体的例子。

学生是什么?入学者?参加研究的人?残酷现实社会的避难者?有姓名和一系列考试分数的人?显然,最后一个定义完全没有表示出人的特征,但非常适合于简单的计算机表示。因此,让我们根据该定义来开发 Student 类。

将学生简化成姓名和一组考试分数后,可以使用一个包含两个成员的类来表示它:一个成员用于表示姓名,另一个成员用于表示分数。对于姓名,可以使用字符数组来表示,但这将限制姓名的长度。当然,也可以使用 char 指针和动态内存分配,但正如第12章指出的,这将要求提供大量的支持代码。一种更好的方法是,使用一个由他人开发好的类的对象来表示。例如,可以使用一个String类(参见第 12章)或标准 C++ string 类的对象来表示姓名。较简单的选择是使用 string类,因为 C++库提供了这个类的所有实现
代码,且其实现更完美。要使用 String类,您必须在项目中包含实现文件 string1.cpp。对于考试分数,存在类似的选择。可以使用一个定长数组,这限制了数组的长度;可以使用动态内存分配并提供大量的支持代码:也可以设计一个使用动态内存分配的类来表示该数组;还可以在标准C++库
中查找一个能够表示这种数据的类。自己开发这样的类一点问题也没有。开发简单的版本并不那么难,因为 double 数组与 char 数组有很多相似之处,因此可以根据 String类来设计表示 double 数组的类。事实上,本书以前的版本就这样做过。当然,如果C++库提供了合适的类,实现起来将更简单。C++库确实提供了一个这样的类,它就是valarray。


提示:以下是本篇文章正文内容,下面案例可供参考

一、14.1.1 valarray 类简介

valarray 类是由头文件 valarray 支持的。顾名思义,这个类用于处理数值(或具有类似特性的类),它支持诸如将数组中所有元素的值相加以及在数组中找出最大和最小的值等操作。valarray 被定义为一个模板类,以便能够处理不同的数据类型。本章后面将介绍如何定义模板类,但就现在而言,您只需知道如何使用模板类即可。

14.1.3 Student 类示例

现在需要提供 Student 类的定义,当然它应包含构造函数以及一些用作 Student 类接口的方法。程序清单 14.1是 Student 类的定义,其中所有构造函数都被定义为内联的:它还提供了一些用于输入和输出的友元函数。

程序清单14.1 studentc.h

#ifndef __STUDENTC14_1_H__
#define __STUDENTC14_1_H__

#include <iostream>
#include <valarray>
#include <string>

class Student
{
private:
	typedef std::valarray<double> ArrayDb;
	std::string name;	//contained object
	ArrayDb scores;	//contained object
	//private method for scores output 
	std::ostream &arr_out(std::ostream &os) const;
public:
	Student() : name("Null Student"), scores() {}
	explicit Student(const std::string &s) 
		: name(s), scores() {}
	explicit Student(int n) : name("Nully"), scores(n) {}
	Student(const std::string &s, int n) : name(s), scores(n) {}
	Student(const std::string &s, const ArrayDb &a) : name(s), scores(a) {}
	Student(const char *str, const double *pd, int n) : name(str), scores(pd, n) {}
	~Student() {}
	double Average() const;
	const std::string &Name() const;
	double &operator[](int i);
	double operator[](int i) const;
	// friend
	//input
	friend std::istream &operator>>(std::istream &is, Student &stu); //1 word per line
	friend std::istream &getline(std::istream &is, Student &stu);	//1 line
	//output
	friend std::ostream &operator<<(std::ostream &os, const Student &stu);
};

#endif /* __STUDENTC14_1_H__ */



为简化表示,Student类的定义中包含下述typedef:typedef std::valarray ArrayDb;

请注意关键字 explicit 的用法:

explicit student(const std::string&s)
:name(s)scores(){}
explicit Student(int n):name("Nully"),scores(n){}

本书前面说过,可以用一个参数调用的构造函数将用作从参数类型到类类型的隐式转换函数;但这通常不是好主意。在上述第二个构造函数中,第一个参数表示数组的元素个数,而不是数组中的值,因此将一个构造函数用作 int 到 Student 的转换函数是没有意义的,所以使用 explicit 关闭隐式转换。如果省略该关键字,则可以编写如下所示的代码:

Student doh("Homer",10);//store "Homer", create array of 10 elements
doh =5;//reset name to "Nully",reset to empty array of 5 elements

在这里,马虎的程序员键入了 doh 而不是 doh[0]。如果构造函数省略了explicit,则将使用构造函数调用 Student(5)将5转换为一个临时 Student对象,并使用“Nully”来设置成员name的值。因此赋值操作将使用临时对象替换原来的 doh值。使用了explicit后,编译器将认为上述赋值运算符是错误的。


总结

提示:这里对文章进行总结:

1,explicit 使用
2,valarray 的使用

  • 29
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值