c++ primer 学习笔记3

合集下载

C++Primer第3章

C++Primer第3章

1. 除基本类型外,C++还定义了一个内容丰富的抽象数据类型标准库。

其中最重要的库类型是string,vector, bitset。

string定义了大小可变的字符串,vector定义了大小可变的集合。

Bitset 提供了一种抽象的方法来操作位集合,与整型值上的内置位操作符相比,bitset类提供了一种更方便的处理位的方式。

通过这个类可以把革个值当作位的集合来处理。

与第5章介绍的位操作符相比,该类提供了更直接的操作位的方法。

String和vector往往将迭代器用作配套类型,用于访问string中的字符或者vector中的元素。

这些标准库类型是语言组成部分中更基本的数据(如数组和指针)的抽象。

当然我们在第4章还会学到类似于string和vector类型的内容。

但是标准库中提供的string和vector类型可能更灵活,且不容易出错。

本章介绍标准库中的vector,string,bitset, 迭代器。

第4章会讨论数组和指针,第5章会讨论内置位操作符。

我们以上讨论的string和vector都是更高级的抽象数据类型。

之所以说它们更高级,是因为其中反映了更复杂的概念;之所以说它们是抽象的,是因为我们在使用时不需要关心它们是如何表示的,只需要知道它们支持那些操作就可以了。

2. 以前我们都是通过直接说明名字来知std空间来引用标准库中的名字的。

比入:std::cin. 我们用::操作符。

它是作用域操作符。

其含义是,右操作数的名字可以在左操作数的作用域中找到。

因此std::cin的意思是说所需名字cin可以在命名空间std中定义的。

显然,这样非常麻烦。

C++提供了更简洁的方式来使用命名空间。

使用using声明是一种最安全的机制。

在没有using声明的情况下,直接使用命名空间中名字的未限定版本是错误的。

尽管有些编译器也许无法检测出这种错误。

一个using声明一次只能作用于一个命名空间成员。

Using声明可用来明确指定在程序中用到的命名空间中的名字。

C++Primer第三章~第六章个人总结

C++Primer第三章~第六章个人总结
转换为 int。具体的,true 被转换为 1,false 被转换为 0。这些转换被称为整型提升。 例如:short chickens = 20; short ducks = 35; short fowls = chickens + ducks; 为执行第三行语句,C++程序取得 chickens 和 ducks 的值,并将它们转换为 int。然后程
然而 new 运算符可以避开这种限制。
·数组之所以称为复合类型,因为它是使用其它类型来创建的。
·sizeof 运算符返回类型或数据对象的长度(单位为字节)。将 sizeof 用于数组名,得到 的将是整个数组中的字节数。将 sizeof 用于数组元素,得到的将是元素的长度(单位为字节)。
·数组的初始化:
(4)如果初始化数组时方括号内([])为空,C++编译器将计算元素个数。例如: short a[] = {1,2,3,4};编译器将使 a 数组包含 4 个元素。
可以通过下面方法获得数组元素个数:
short things[] = (1,2,3,4);
int num_elements = sizeof(things)/sizeof(short);
·C++11 版本校验表: (1)如果有一个操作数的类型时 long double,则将另一个操作数类型转换为 long double (2)否则,如果有一个操作数的类型是 double,则将另一个操作数转换为 double。 (3)否则,如果有一个操作数的类型是 float,则将另一个操作数转换为 float。 (4)否则,说明操作数都是整型,因此执行整型提升。 (5)在这种情况下,如果两个操作数都是有符号或无符号的,且其中一个操作数的级 别比另一个低,则转换为级别高的类型。 (6)如果一个操作数是有符号的,另一个操作数是无符号的,且无符号操作数的级别 比有符号操作数高,则将有符号操作数转换为无符号操作数所属的类型。 (7)否则,如果有符号类型可表示无符号类型的所有可能取值,则将无符号操作数转 换为有符号操作数所属的类型。 (8)否则,将两个操作数都换为有符号类型的无符号版本。 ·有符号整型按级别从高到低依次为 long long、long、int、short 和 signed char。无符号整型 的排列顺序与有符号整型相同。类型 char、signed char 和 unsigned char 的级别相同。类型 bool 的级别最低。 ·强制类型转换: (long) thorn 或 long (thorn),强制类型转换不会修改 thorn 变量本身,而是创建一个新的,指 定类型的值。

【读书】CPrimer读书笔记

【读书】CPrimer读书笔记

【关键字】读书(从后向前看)标题:重载函数再论重载函数是C++提出来的概念,但是在C中却未必没有。

比如“1+3”和“1.0+,虽然都是加法,做的却不是同的操作:编译器要因操作数的不同而调用不同的加法操作。

只是C语言中除了内部类型变量可以参与运算以外,没有“类”这么高深的概念。

“结构体”也只是内存数据的组织方法,而不涉及对整个结构体的处理。

所以,在C语言时代编译器明明做了类似于重载的事情,却可以像雷锋一样“做好事不留名”。

C++发展出了类,并且赋予了“类”很高的期望,类的东西也能像内置类型东西一样参与一切运算。

那么,就拿加法运算来说,编译器如何知道对某类东西的加法该调用哪一个详细的操作代码?于是,即使不出现普通函数的重载,至少运算符是要重载的。

博士在《高质量C++/C编程指南》中为重载函数的必要性提了另一个理由:类的构造函数名称必须与类名相同,而类却经常要定义多个不同的构造函数。

那就只好重载了。

对于普通程序员来说,我们完全可以不用考虑得这么深。

重载函数给我们至少还带来了另一个好处:不用记忆多个不同的函数名了,也不用为了给函数起名而绞尽脑汁了。

不过本书还给出了一个建议:并不是任何时候都有必要重载函数的,有的时候不同的函数名可以直观地带来好多信息,滥用重载只是牺牲了名称中的信息。

标题::重载函数的概念引用:出现在相同作用域中的两个(可以是两个以上——偷猫注)函数,如果具有相同的名字而形参表不同,则称为重载函数。

本节开头第一句话就给出了重载函数的定义:重载函数必须符合两个条件:一是出现在相同的作用域中、二是函数名字相同而形参表不同。

其中第一个条件一般人往往是不去想的,其实函数名相同而作用域不同的函数大大存在,比如在MFC中就有。

它们是完全不相干的函数。

第二个条件还可以详说一下:函数名字相同当然不在话下,这是函数被称为“重载”的根源。

之于形参表不同,可能表现在形参个数不同、可能表现在形参类型不同、还可能表现在形参顺序不同。

c++ primer plus第六版学习笔记

c++ primer plus第六版学习笔记

笔记目录第一章:预备知识 (5)1、c++简介 (5)2、程序创建技巧 (5)3、源文件扩展名 (5)第二章:开始学习c++ (5)1、c++代码区分大小写。

(5)2、c++代码结构 (5)3、函数 (6)4、注译 (6)5、c++预处理器和iostream文件 (6)6、头文件名 (6)7、名称空间 (7)8、cout进行c++输出 (7)9、控制符endl (7)10、c++代码格式 (7)C++语句 (7)1、声明语句和变量 (7)2、赋值语句 (7)3、cout的新用法 (8)4、使用cin (8)5、使用cout拼接 (8)6、类简介 (8)7、函数 (8)8、函数原型 (9)9、使用库函数 (10)10、函数变体 (10)12、函数格式 (11)14、复习int main()函数头 (12)15、关键字 (12)16、用户定义有返回值的函数 (13)17、多函数程序中使用using指令 (14)总结 (14)复习题 (14)编程练习 (15)第三章、处理数据 (17)1、简单变量 (17)2、变量名 (18)3、整型 (18)4、整型short、int、long和long long (18)※注译:位与字节 (18)要了解的概念: (19)5、运算符sizeof和头文件limits (20)符号常量-预处理器方式(注译) (21)6、初始化 (21)c++初始化方式 (21)7、无符号类型 (22)8、选择整数类型 (23)9、整型字面值 (24)10、C++如何确定常量的类型 (25)11、char类型:字符和小整数 (26)成员函数cout.put() (27)Char字面值and转义序列 (27)通用字符名 (28)signed char和unsigned char (29)wcha_t (29)C++11新增的类型:char16_t和char32_t (29)12、const限定符(定义符号常量) (30)13、浮点数 (30)书写浮点数 (31)浮点类型 (31)浮点常量 (32)浮点数的优缺点 (33)将类型分类*注译 (33)13、c++算术符 (33)运算符优先级和结合性 (34)除法分支 (34)运算符重载(注译) (34)求模运算符 (35)类型转换 (36)14、总结 (38)15、第三章复习题 (39)16、编程练习 (40)第四章、复合类型 (40)1、数组 (40)3、数组的初始化规则 (42)4、c++数组初始化方法 (42)5、字符串 (43)拼接字符串常量 (43)在数组中使用字符串 (43)字符串输入 (45)每次读取一行字符串输入 (46)混合输入字符串和数字 (47)6、string类简介 (48)C++11字符串初始化 (49)赋值、拼接和附加 (49)String类的其他操作(包含了确定字符数函数) (50)String类I/O (50)其他形式的字符串面值 (52)7、结构简介 (52)在程序中使用结构 (53)C++结构初始化 (55)结构可以将string类作为成员吗 (56)其他结构属性 (56)结构数组 (56)结构中的位字段 (57)9、共用体 (57)10、枚举 (58)设置枚举量的值 (59)枚举的取值范围 (59)11、指针和自由存储空间 (59)声明和初始化指针 (61)指针的危险 (62)指针和数字 (63)使用new来分配内存 (63)使用delete释放内存 (64)使用new来创建动态数组 (65)12、指针、数组和指针算术 (67)指针小结 (69)指针和字符串 (71)使用new创建动态结构 (73)第一章:预备知识1、c++简介c面向过程,c++面向对象。

《C++Primer》笔记第3章字符串、向量和数组

《C++Primer》笔记第3章字符串、向量和数组

《C++Primer》笔记第3章字符串、向量和数组1.位于头文件的代码一般来说不应该使用using声明。

2.如果使用等号(=)初始化一个变量,实际上执行的是拷贝初始化,编译器把等号右侧的初始值拷贝到新创建的对象中去。

与之相反,如果不使用等号,则执行的是直接初始化。

3.string对象会自动忽略开头的空白(即空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇见下一处空白为止。

4.string类的size函数返回的是一个string::size_type类型的值,它是一个无符号类型的值而且能足够存放下任何string对象的大小。

所有用于存放string类的size函数返回值的变量,都应该是string::size_type类型的。

由于size函数返回的是一个无符号整型数,因此切记,如果在表达式中混用了带符号数和无符号数将可能产生意想不到的结果。

5.如果一条表达式中已经有了size()函数就不要再使用int了,这样可以避免混用int和unsigned可能带来的问题。

6.当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符(+)的两侧的运算对象至少有一个是string。

7.C++语言中的字符串字面值并不是标准库类型string的对象。

切记,字符串字面值与string是不同的类型。

type头文件中的函数函数解释isainum(c) 当c是字母或数字时为真isalpha(c) 当c是字母时为真iscntrl(c) 当c是控制字符时为真isdigit(c) 当c是数字时为真isgraph(c) 当c不是空格但可打印时为真islower(c) 当c是小写字母时为真isprint(c) 当c是可打印字符时为真(即c是空格或c具有可视形式)ispunct(c) 当c是标点符号时为真(即c不是控制字符、数字、字母、可打印空白中的一种)函数解释isspace(c) 当c是空白时为真(即c是空格、横向制表符、纵向制表符、回车符、换行符、进纸符中的一种)isupper(c) 当c是大写字母时为真isxdigit(c) 当c是十六进制数字时为真tolower(c) 如果c是大写字母,输出对应的小写字母;否则原样输出ctoupper(c) 如果c是小写字母,输出对应的大写字母;否则原样输出c9.范围for语句遍历给定序列中的每个元素并对序列中的每个值执行某种操作,其语法形式是:10.for (declaration : expression)11.statement12.访问string对象的下标运算符([])接受的输入参数是string::size_type类型的值,这个参数表示要访问的字符的位置;返回值是该位置上字符的引用。

Primer(第四版) 函数部分笔记

Primer(第四版) 函数部分笔记

在定义或声明函数时,没有显式指定返回类型是不合法的。

早期的C++ 版本可以接受这样的程序,将test 函数的返回类型隐式地定义为int 型。

但在标准C++ 中,上述程序则是错误的。

形参表的类型:直接复制方式;(不改变实参值)指针方式;(改变指向的内存的值)引用方式;(改变实参的值)复制实参并不是在所有的情况下都适合,不适宜复制实参的情况包括:• 当需要在函数中修改实参的值时。

• 当需要以大型对象作为实参传递时。

对实际的应用而言,复制对象所付出的时间和存储空间代价往往过高。

(不需要改变实参值时,内置内省一般实行赋值的方式,速度较快;类类型情况下,实行const &方式,引用的方式速度较快)• 当没有办法实现对象的复制时(流对象)。

1.对于复制实参的函数:参数传递时,允许隐式类型转换;2.对于非const引用函数:调用这样的函数时,传递一个右值(const类型)或具有需要类型转换的对象同样是不允许的,只能与完全同类型的非const 对象关联。

3.对于const引用函数:则允许隐式类型转换,或者传递字面值常量。

4.上述情况的原因是,当初学习引用的时候,赋值遵循以下规则:·首先,引用变量必须初始化;·非const引用变量仅可以初始化为同类型的变量;·const引用变量可以初始化为任何类型的变量或字面值常量,即允许变量类型的隐式转换,但不可以改变原始的实参值。

容器类型的函数:1. 通常,函数不应该有非引用vector 形参。

调用含有普通的非引用vector 形参的函数将会复制vector 的每一个元素。

2. 应考虑将形参声明为引用类型,因为非引用形参(复制方式传递)是基于不改变实参,仅对内置类型高效,其他类型尽量使用const引用、引用方式传递。

3. 事实上, C++ 程序员倾向于通过传递指向容器中需要处理的元素的迭代器来传递容器。

void print(vector::const_iterator beg,vector::const_iterator end)1.定义数组函数时,形参的方式可以是指针或引用;2. 需要修改数组形参的元素时,最好函数将形参定义为:void f (int*) 或者void (int a[ ])3. 不需要修改数组形参的元素时,最好函数将形参定义为:void f (const int*)指向const 对象的指针4. 多维数组时:void f (int a[][10], int rowSize);数组的其中一种编程风格:(类似容器)调用这种风格的函数需要传递两个指针:传递指向数组第一个和最后一个元素的下一个位置的指针。

C PRIMER笔记

C++Primer笔记leilei2013-8-2目录第二章开始学习c++ (1)第三章数据处理 (1)3.1简单变量 (1)3.2const限定符 (2)3.3浮点数 (2)3.4c++算术操作符 (2)第四章复合类型 (2)4.1数组(array) (2)4.2字符串 (3)4.3string类简介 (4)4.4结构(struct)简介 (4)4.5共用体(union) (5)4.6枚举类型(enum) (5)4.7指针和自由存储空间 (5)4.8指针、数组和指针算术 (6)第五章循环和关系表达式 (7)5.3while循环 (7)5.5循环文本输入 (8)5.6嵌套循环和二维数组 (8)第六章分支语句和逻辑操作符 (8)第七章函数——c++的程序模块 (9)7.3函数与数组 (9)7.9函数指针 (9)第八章函数探幽 (10)8.1内联函数 (10)8.2引用变量 (10)8.3默认参数 (12)8.4函数重载 (12)8.5函数模板 (12)8.6总结 (13)第九章内存模型和名称空间 (14)9.1单独编译 (14)9.2存储持续性、作用域和链接性 (14)9.3布局new操作符 (15)9.4名称空间 (15)第十章对象和类 (16)10.1过程性编程和面向对象编程 (16)10.2抽象和类 (16)10.3类的构造函数和析构函数 (18)10.4this指针 (19)10.5对象数组 (19)10.7类作用域 (19)10.9总结 (19)第十一章使用类 (20)11.1操作符重载 (20)11.6类的自动转换和强制类型转换(未看) (21)第十二章类的动态分配内存 (21)12.3总结 (23)第十三章类继承 (23)13.1公有派生 (23)13.2有关派生类构造函数的要点 (24)13.3继承——is-a关系 (24)13.4多态公有继承 (24)13.5访问控制:protected (25)13.6抽象基类 (26)13.7继承和动态内存分配 (26)13.8类设计回顾 (27)第十四章C++中的代码重用 (29)14.1包含对象成员的类 (29)14.2私有继承 (29)14.3多重继承(MI) (30)14.4类模板 (32)14.5总结 (32)第十五章友元、异常和其他 (33)15.1友元 (33)15.2嵌套类 (33)15.3异常 (34)15.4RTTI (34)第十六章string类和标准模板库 (35)16.1string类 (35)16.3STL (36)16.4通用编程技术 (37)c++源代码风格1每行一条语句2每个函数的两个花括号各占一行3函数中的语句都对于花括号进行缩进4与函数名称相关的圆括号周围没有空白(空行将声明语句与程序的其他部分分开,或在变量前声明,c++的做法是尽可能在首次使用变量前声明)。

C Primer Plus(第五版)学习笔记

C Primer Plus(第五版)学习笔记第一章概览1.1 C语言的起源记住Dennis Ritchie和Ken Thomson。

是在设计UNIX操作系统的时候开发的。

1.2 使用C语言的理由C是一种融合了控制特性的现代语言,而我们已发现在计算机科学的理论和实践中,控制特性是很重要的。

其设计使得用户可以自然地采用自顶向下的规划、结构化的编程,以及模块化的设计。

这种做法使得编写出的程序更可靠、更易懂。

C是一种高效的语言。

C程序往往很紧凑且运行速度快。

C是一种可移植语言。

由于C与UNIX的紧密联系,UNIX系统通常都带有一个C编译器作为程序包的一部分。

Linux中同样也包括一个C 编译器。

C强大而又灵活(计算机世界中经常使用的两个词)。

C面向编程人员的需要。

它允许您访问硬件,并可以操纵内存中的特定位。

它具有丰富的运算符供选择,让您能够简洁地表达自己的意图。

多数C实现都有一个大型的库,其中包含有用的C函数。

这些函数能够处理编程人员通常会面对的许多需求。

C的简洁性与其丰富的运算符相结合,使其可能会编写出极难理解的代码。

没有谁强迫您编写含糊难懂的代码,但存在这样的可能性。

试问,除C之外还有哪种语言存在一年一度的“含糊代码”(ObfuscatedCode)竞赛呢?1.3 C语言的发展方向不管C++和Java这些较新的语言如何流行,C在软件产业仍然是一种重要的技能,在最想获得的技能中,它一般都列在前10名。

特别是在嵌入式系统的编程中,C已开始流行。

也就是说,它将用来为汽车、照相机、DVD播放器和其他现代化设备中逐渐普及的微处理器编程。

同样,C已开始进入长期以来一直属于FORTRAN的科学编程领域。

最后,由于它是一种适合用来开发操作系统的语言,C在Linux的开发中也扮演着重要的角色。

1.4 计算机工作的基本原理CPU的工作非常简单,至少在我们所做的这一简短描述中是这样的。

它从内存中获取一个指令并执行该指令,然后从内存中获取下一个指令并执行。

Primer(第四版) 学习笔记

在字符中使用单引号、反斜杠时要使用转义字符;在字符串中使用双引号、反斜杠时要使用转义字符;\?可以不必使用转义字符,直接使用?即可;C++ 语言从C 语言中继承下来的预处理器变量NULL,该变量在cstdlib头文件中定义,其值为0。

如果在代码中使用了这个预处理器变量,则编译时会自动被数值0 替换。

·大多数编译器,包括那些来自IDE 的,都提供了命令行界面。

除非你已经很熟悉你的IDE,否则从使用简单的命令行界面开始可能更容易些。

这样可以避免在学习语言之前得先去学习IDE。

表示整数、字符和布尔值的算术类型合称为整型。

bool 类型表示真值true 和false。

可以将算术类型的任何值赋给bool 对象。

0 值算术类型代表false,任何非0 的值都代表true。

除bool 类型外,整型可以是带符号的(signed)也可以是无符号的(unsigned)。

整型int、short 和long 都默认为带符号型。

要获得无符号型则必须指定该类型为unsigned,比如unsigned long。

unsigned int 类型可以简写为unsigned,也就是说,unsigned 后不加其他类型说明符意味着是unsigned int 。

1定义变量、指针最好在要使用之前定义,定义紧跟着使用,可读性强,也安全。

2定义变量、指针最好定义时就初始化,除非确定之后就要初始化,养成好习惯。

3如果必须分开定义指针和其所指向的对象,则将指针初始化为 0。

因为编译器可检测出 0 值的指针,程序可判断该指针并未指向一个对象。

对于内置类型的初始化:当为全局变量或静态变量时,没进行初始化的话,系统自行初始化为0;当为局部变量时,系统也不进行初始化,使用则出错。

在数组中时,也同理。

但是,假如仅初始化了其中的一个元素,则系统会自动初始化之后的元素,如:int型仅初始化第一个,之后的系统默认初始化为0;char 型仅初始化第一个元素,之后的系统默认初始化为'\0'对于类类型的初始化:无论是全局变量还是局部变量,米有进行初始化的话,其都将调用自己定义时的默认构造函数(不是构造函数)。

C++Primer读书笔记

C++Primer读书笔记第一章快速入门1. 每个C++程序都包含一个或多个函数,而且必须有一个命名为main。

函数由执行函数功能的语句序列组成;2. main函数是唯一被操作系统显式调用的函数;3. main函数的形参个数是有限的4. 函数体是函数定义的最后部分,是以花括号开始并以花括号结束的语句块;5. 注释不会增加可执行程序的大小,编译器会忽略所有注释;6. 我们注释的风格是在注释的每一行以星号开始,指明整个范围是多行注释的一部分;7. 我们倾向于把确定函数边界的花括号自成一行,且缩进复合的输入或输出表达式从而使操作符排列整齐;8. 标准库的头文件用尖括号< >括起来,非标准库的头文件用双引号“ ”括起来;第一部分基本语言第二章变量和基本类型1. wchar_t类型用于扩展字符集,比如汉字和日语,这些字符集中的一些字符不能用单个char表示;2. 在位这一级上,存储器是没有结构和意义的;让存储具有结构的最基本方法是用块处理存储;3. 建议:使用内置算术类型;4. 只有内置类型存在字面值,没有类类型的字面值,也没有任何标准库类型的字面值;5. 没有short类型的字面值常量;6. 不可打印字符和特殊字符都用转义字符书写,转义字符都以反斜线符号开始;7. 未定义行为源于编译器不能检测到的程序错误或太麻烦一直无法检测的错误;8. C++是一门静态类型语言,在编译时会做类型检查;9. 左值可以出现在赋值语句的左边或右边,右值只能出现在的赋值语句的右边;10. 变量是左值,数字字面值是右值;11. 对象就是内存中具有类型的区域;12. 标识符不能包含两个连续的下划线,也不能以下划线开头后面紧跟一个大写字母。

有些标识符(在函数外定义的标识符)不能以下划线开头;13. C++支持两种初始化变量的形式:复制初始化和直接初始化。

复制初始化语法用等号(=),直接初始化则把初始化式放在括号中;14. 初始化不是复制:初始化指创建变量并给它赋初始值,而赋值则是擦除对象的当前值并用新值代替;15. 在函数体外定义的变量都初始化成0,在函数体里定义的内置类型变量不进行自动初始化;16. 在一个程序中,变量有且仅有一个定义,但可以声明多次。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

包含对象成员的类valarray类是由头文件valarray支持的。

顾名思义,这个类用于处理数值,他支持诸如将数组中的所有元素的值想家以及在数组中找出最大和最小的值等操作。

valarray被定义为一个模板类,以便能够处理不同的数据类型。

一个Student类----一个getline导致构造函数递归的类[cpp]view plaincopyprint?1.// readBook2.cpp : 定义控制台应用程序的入口点。

2.//3.4.#include "stdafx.h"5.#include "iostream"ing namespace std;7.#include "valarray"8.#include "string"9.10.class CStudent11.{12.public:13.typedef std::valarray<double> ArrayDb;14. CStudent() : sz_Name( "Null Student" ), m_ArrScores()15. {16. }17. CStudent( const string& name ) : sz_Name( name), m_ArrScores()18. {19. }20.explicit CStudent( int n ) : sz_Name( "Nully"), m_ArrScores( n )21. {22. }23. CStudent( const string& name, int n ) : sz_Name( name ), m_ArrScores( n )24. {25. }26. CStudent( const string& name, const ArrayDb& a) : sz_Name( name ), m_ArrScores( a )27. {28. }29. CStudent( const char* name, const double* pd,int n ) : sz_Name( name ), m_ArrScores( pd, n )30. {31. }32.double Average() const33. {34.if ( m_ArrScores.size() > 0 )35. {36.return ( m_ArrScores.sum() / m_ArrScores.size() );37. }38.else39. {40.return 0;41. }42. }43.const string& GetName() const44. {45.return sz_Name;46. }47.double& operator[]( int i)48. {49.return m_ArrScores[ i ];50. }51.double operator[]( int i ) const52. {53.return m_ArrScores[ i ];54. }55. ostream& CStudent::arr_out( ostream& os ) const56. {57.int i;58.int lim = m_ArrScores.size();59.if ( lim > 0 )60. {61.for ( i = 0; i < lim; i++ )62. {63. os << m_ArrScores[ i ] << " ";64.if ( 4 == i % 5 )65. {66. os << endl;67. }68. }69.if ( 0 != i % 5 )70. {71. os << endl;72. }73. }74.else75. {76. os << "empty array";77. }78.return os;79. }80.friend istream& operator >>( istream& is, CStudent& stu );81.friend istream& operator <<( istream& os, const CStudent& stu );82.friend istream& getline( istream& is, const CStudent& stu );83. ~CStudent(){};84.private:85. string sz_Name;86. ArrayDb m_ArrScores;87.};88.89.istream& operator >>( istream& is, CStudent& stu )90.{91. is >> stu.sz_Name;92.return is;93.}94.95.ostream& operator <<( ostream& os, const CStudent&stu )96.{97. os << "this student name is:" << stu.GetName() << endl;98. os << "this student scores is:" << endl;99. stu.arr_out( os );100.return os;101.}102.istream& getline( istream& is, const CStudent& stu )103.{104. getline( is, stu.sz_Name );105.return is;106.}107.108.const int puplis = 3;109.const int quizzes = 5;110.void set( CStudent& sa, int n );111.112.int _tmain(int argc, _TCHAR* argv[])113.{114. CStudent ada[ puplis ] = { CStudent( quizze s ), CStudent( quizzes ), CStudent( quizzes ) }; 115.int i;116.for ( i = 0; i < puplis; ++i )117. {118. set( ada[ i ], quizzes );119. }120. cout << "\nStudent List:" << endl;121.for ( i = 0; i < puplis; ++i )122. {123. cout << ada[ i ].GetName() << endl; 124. }125. cout << "\nResults:" << endl;126.for ( i = 0; i < puplis; i++ )127. {128. cout << endl << ada[ i ];129. cout << "average" << ada[ i ].Average() << endl;130. }131. cout << "Done." << endl;132.133.return 0;134.}135.136.void set( CStudent& sa, int n )137.{138. cout << "Please enter the student name:" << endl;139. getline( cin, sa );140. cout << "Please enter " << n << "quiz score s:" << endl;141.for ( int i = 0; i < n; i++ )142. {143. cin >> sa[ i ];144. }145.while( '\n' != cin.get() )146. {147.continue;148. }149.}// 在istream& getline( istream& is, const CStudent& stu ){getline( is, stu.sz_Name );return is;}//const CStudent& stu导致递归修改之后的版本[cpp]view plaincopyprint?1.// readBook2.cpp : 定义控制台应用程序的入口点。

2.//3.4.#include "stdafx.h"5.#include "iostream"ing namespace std;7.#include "valarray"8.#include "string"9.10.class CStudent11.{12.public:13.typedef std::valarray<double> ArrayDb;14. CStudent() : sz_Name( "Null Student" ), m_ArrScores()15. {16. }17. CStudent( const string& name ) : sz_Name( name), m_ArrScores()18. {19. }20.explicit CStudent( int n ) : sz_Name( "Nully"), m_ArrScores( n )21. {22. }23. CStudent( const string& name, int n ) : sz_Name( name ), m_ArrScores( n )24. {25. }26. CStudent( const string& name, const ArrayDb& a) : sz_Name( name ), m_ArrScores( a )27. {28. }29. CStudent( const char* name, const double* pd,int n ) : sz_Name( name ), m_ArrScores( pd, n )30. {31. }32.double Average() const34.if ( m_ArrScores.size() > 0 )35. {36.return ( m_ArrScores.sum() / m_ArrScores.size() );37. }38.else39. {40.return 0;41. }42. }43.const string& GetName() const44. {45.return sz_Name;46. }47.double& operator[]( int i)48. {49.return m_ArrScores[ i ];50. }51.double operator[]( int i ) const52. {53.return m_ArrScores[ i ];55. ostream& CStudent::arr_out( ostream& os ) const56. {57.int i;58.int lim = m_ArrScores.size();59.if ( lim > 0 )60. {61.for ( i = 0; i < lim; i++ )62. {63. os << m_ArrScores[ i ] << " ";64.if ( 4 == i % 5 )65. {66. os << endl;67. }68. }69.if ( 0 != i % 5 )70. {71. os << endl;72. }73. }74.else75. {76. os << "empty array";77. }78.return os;79. }80.friend istream& operator >>( istream& is, CStudent& stu );81.friend istream& operator <<( istream& os, const CStudent& stu );82.friend istream& getline( istream& is, CStudent& stu );83. ~CStudent(){};84.private:85. string sz_Name;86. ArrayDb m_ArrScores;87.};88.89.istream& operator >>( istream& is, CStudent& stu )90.{91. is >> stu.sz_Name;92.return is;93.}94.95.ostream& operator <<( ostream& os, const CStudent&stu )96.{97. os << "this student name is:" << stu.GetName() << endl;98. os << "this student scores is:" << endl;99. stu.arr_out( os );100.return os;101.}102.istream& getline( istream& is, CStudent& stu )103.{104. getline( is, stu.sz_Name );105.return is;106.}107.108.const int puplis = 3;109.const int quizzes = 5;110.void set( CStudent& sa, int n );111.112.int _tmain(int argc, _TCHAR* argv[])113.{114. CStudent ada[ puplis ] = { CStudent( quizze s ), CStudent( quizzes ), CStudent( quizzes ) }; 115.int i;116.for ( i = 0; i < puplis; ++i )117. {118. set( ada[ i ], quizzes );119. }120. cout << "\nStudent List:" << endl;121.for ( i = 0; i < puplis; ++i )122. {123. cout << ada[ i ].GetName() << endl; 124. }125. cout << "\nResults:" << endl;126.for ( i = 0; i < puplis; i++ )127. {128. cout << endl << ada[ i ];129. cout << "average" << ada[ i ].Average() << endl;130. }131. cout << "Done." << endl;132.133.return 0;134.}135.136.void set( CStudent& sa, int n )137.{138. cout << "Please enter the student name:";139. getline( cin, sa );140. cout << "Please enter " << n << "quiz score s:" << endl;141.for ( int i = 0; i < n; i++ )142. {143. cin >> sa[ i ];144. }145.while( '\n' != cin.get() )146. {147.continue;148. }149.}私有继承c++还有另一种实现has-a关系的途径----私有继承。

相关文档
最新文档