码迷,mamicode.com
首页 > 编程语言 > 详细

c++代码重用—student(学习笔记)

时间:2015-05-31 16:34:05      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:

第 14 章——C++中的代码重用

  • 包含对象成员的类

14.1.1 valarray简介

头文件valarray
支持的功能:

  1. 将数组中所用元素的值相加
  2. 找出最大最小值等操作

 

用valarray类声明一个对象

valarray < int > q_values;
valarray < double > weights;

使用构造函数的代码片段

valarray< double > gpa[5] = {3.4,5.6,7.8,5.3,1.2};
valarray < double > v1;
valarray < int > v2(8);// an array of 8 int elements
valarray < int > v3(10,8);//an array of 8 int elements;
                          //each set to 10;
valarray < double > v4(gpa,4)//an array of 4 double elements
                          //initialized to the first 4 elements of gpa;

 

14.1.2students类的设计

typedef std::valarray< double > ArrayDb;

  • 加入typedef的作用:在以后的代码中便可以使用表示ArrayDb

注意关键字explicit

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

上述代码使用explicit关闭隐式转换

 

  • 使用explicit来防止但参数数构造函数的隐式转换,根本原因:在编译阶段出现错误优于在运行阶段出现错误

初始化的顺序

  • 项目被初始化的顺序为他们被声明的顺序
    student(const char* str,const double* pd ,int n):scores(pd,n),name(str){}
    基于上述原则:name成员首先被初始化,因为在类的定义中他首先被声明,所以,在这个例子中初始化顺序并不重要,但是,如果如果一个成员的值作为另一个成员的初始化表达的一部分,初始化顺序就非常重要了。

函数实现

 1 #include
 2 using std::ostream;
 3 using std::endl;
 4 using std::cout;
 5 using std::istream;
 6 using std::string;
 7 
 8 //public methods
 9 double student::average()const
10 {
11     if(scores.size()>0)
12     {
13         return scores.sum()/scores.size();
14     }
15     else
16     {
17         return 0;
18     }
19 }
20 const string & student::Name()const
21 {
22     return name;
23 }
24 double & student::operator [](int i)
25 {
26     return scores[i];
27 }
28 
29 double student::operator [](int i)const
30 {
31     return scores[i];
32 }
33 //私有方法
34 ostream & student::arr_out(std::ostream & os)const
35 {
36     int i;
37     int lim=scores.size();
38     if(lim>0)
39     {
40         for(i=0;i<<<" ";
41             if(i%5==4)//一行5个元素
42                 os<<<<"empty array ";
43         return os;
44     }
45 }
46 //友元函数
47 istream & operator>>(istream & is,student& stu)
48 {
49     is>>stu.name;
50     return is;
51 }
52 //使用string友元函数
53 istream & getline(istream & is,student & stu)
54 {
55     is>>stu.name;
56     return is;
57 }
58 ostream & operator<<(ostream & os,const student& stu)
59 {
60     os<<"scores for: "<<<":\n";
61     //使用私有方法为了成绩的输出
62     stu.arr_out(os);
63     return os;
64 }

 

 

说明:

  • 问题一:使用被包含对象的接口

因为被包含对象的接口不是共有的,这里的接口,我的理解是被包含对象所属类的函数,那如何使用呢?我们可以通过类方法去使用它(在这里是studnet类),比如代码:

double student::average()const
{
	if(scores.size()>0)
	{
		return scores.sum()/scores.size();
	}
	else
	{
		return 0;
	}
}

student调用其作用域内的方法average(),average可以访问student的私用数据,也就是scores对象,scores是valarray的一个对象,自然可以调用它内部的方法

  1. size()
  2. sum()

 

  • 问题二:scores调用自身的类方法

double & student::operator [](int i)
{
	return scores[i];
}

scores[i]会直接调用valarray类中的重载方法:valarray<douoble>::operator[]()

  • 问题三:关于成员函数scores的输出

首先,我们可以先看成员函数name的输出,如下:

ostream & operator<<(ostream & os,const student& stu)
{
	os<<"scores for: "<< stu.name<<":\n";
	return os;
}

之所以可以这么做的原因是:stu.name是string的一个对象,这样会调用string内部的operator << ()重载函数我们是不也可以如法炮制scores呢?当然可以,除非valarray内也包含operator<<()函数,不巧的是,valarray没有这个函数

  • 定义私有辅助函数(类的私有数据里加入函数)
  • std::ostream & arr_out(std::ostream& os)const;
ostream & student::arr_out(std::ostream & os)const
{
	int i;
	int lim=scores.size();
	if(lim>0)
	{
		for(i=0;i< lim;i++)
		{
			os<< scores[i]<< " ";
			if(i%5==4)
			os << endl;
		}
		if(i%5!=0)
		os << endl;
	}
    else
	{
		os<<"empty array ";
		return os;
	}
}

主函数

  • 包含3个对象的一个数组,每个对象包含5个成绩
 1 #include
 2 #include"student.h"
 3 
 4 using std::cin;
 5 using std::cout;
 6 using std::endl;
 7 void set(student & sa,int n);
 8 //两个常量
 9 const int pupils=3;
10 const int quizzes=5;
11 
12 
13 int main()
14 {
15     student ada[pupils]=
16     {student(quizzes),student(quizzes),student(quizzes)};
17 
18     int i;
19     for(i=0;i<pupils;++i) {="" set(ada[i],quizzes);="" }="" cout=""><<"\nstudents list\n";
20     for(i=0;i<pupils;++i) {="" cout=""><< ada[i].Name()<< endl;
21     }
22     cout<<"\nResults:";
23     for(i=0;i< pupils;++i)
24     {
25     cout<< endl<< ada[i];
26          cout<< "average: "<< ada[i].average()<< endl;
27     }
28     cout<< "Done.\n";
29     return 0;
30 }
31 
32 void set(student & sa,int n)
33 {
34     cout<< "请输入学生的名字: ";
35     getline(cin,sa);
36     cout<< "请输入"<< n << "个成绩:\n";
37     for(int i=0;i< n;i++)
38     {
39         cin>>sa[i];
40     }
41     while(cin.get()!=\n)
42         continue;
43 }

函数说明:

  • 问题一:getline(cin,sa);

注意:输入的时候不能有空格

    

  • 问题二:cin>>sa[i];
  • 在set函数的实现中,他会调用,第一条函数,但是,为什么返回类型是引用,这两个函数具体有什么区别呢?
    1 double & student::operator [](int i)
    2 {
    3     return scores[i];
    4 }
    5 
    6 double student::operator [](int i)const
    7 {
    8     return scores[i];
    9 }

     

 

c++代码重用—student(学习笔记)

标签:

原文地址:http://www.cnblogs.com/rupengkun/p/4542026.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!