C++ Primer第一章扩展阅读 1.输入输出流 ios / \ / \ / \ istringstream----istream ostream----ostringstream / \ / \ / \ / \ ifstream iostream ofstream / \ / \ stringstream fstream iostream istream 从流中读取 ostream 写到流中去 iostream 对流进行读写;从 istream 和 ostream 派生而来 fstream ifstream 从文件中读取;由 istream 派生而来 ofstream 写到文件中去;由 ostream 派生而来 fstream 读写文件;由 iostream 派生而来 sstream istringstream 从 string 对象中读取;由 istream 派生而来 ostringstream 写到 string 对象中去;由 ostream 派生而来 stringstream 对 string 对象进行读写;由 iostream 派生而来 cin,cout,clog,cerr是四个全局对象 cerr(无缓冲标准错误)没有缓冲,发送给它的内容立即被输出 clog(缓冲标准错误) 有缓冲,缓冲区满时输出 cout标准输出 三个都是ostream类定义的输出流对象, cout是在终端显示器输出,cout流在内存中对应开辟了一个缓冲区,用来存放流中的数据,当向cout流插入一个endl,不论缓冲区是否漫了,都立即输出流中所有数据,然后插入一个换行符. cerr流对象是标准错误流,指定为和显示器关联,和cout作用差不多,有点不同就是cout 通常是传到显示器输出,但可以被重定向输出到文件,而cerr流中的信息只能在显示器输出.clog流也是标准错误流,作用和cerr一样,区别在于cerr不经过缓冲区,直接向显示器输出信息,而clog中的信息存放在缓冲区,缓冲区满或者遇到endl时才输出. 2.运算符重载 资料来自http://blog.csdn.net/zgl_dm/article/details/1767201 运算符重载的实质就是函数重载 运算符函数定义一般如下 <返回类型说明符>operator<运算符符号>(<参数表>) { <函数体> } 运算符重载时要遵循以下规则 1)除了类属关系运算符".",成员指针运算符".",作用域运算符"::",sizeof运算符和三目运算符"?:"以外C++中的所有运算符都可以重载。 2)重载运算符限制在C++语言中已有的运算符范围内允许重载的运算符之中不能创建新的运算符。 3)运算符重载实质上函数重载因此编译程序对运算符重载的选择,遵循函数重载的选择原则。 4)重载之后的运算符不能改变运算符的优先级和结核性也不能改变运算符操作个数及语法结构 5)运算符重载不能改变运算符用于内部类型对象的含义.它只能和用户自定义类型的对象一起使用或者用于用户自定义类型的对象和内部类型的对象混合使用时。 6)运算符重载是针对新类型数据的实际需要对原有运算符进行适当的改造,重载的功能应当与原有功能相类似,避免没有目的的使用重载运算符。 运算符重载一般有两种形式:重载为类的成员函数和重载为类的非成员函数。非成员函数通常是友元.(可以把一个运算符作为一个非成员、非友元函数重载。但是,这样的运算符函数访问类的私有和保护成员时,必须使用类的公有接口中提供的设置数据和读取数据的函数,调用这些函数时会降低性能。可以内联这些函数以提高性能) 成员函数运算符 运算符重载为类的成员函数的一般格式为: <函数类型> operator <运算符>(<参数表>) { <函数体> } 当运算符重载为类的成员函数时,函数的参数个数比原来的操作数要少一个(后置单目运算符除外),这是因为成员函数用this指针隐式地访问了类的一个对象,它充当了运算符函数最左边的操作数。因此: (1) 双目运算符重载为类的成员函数时,函数只显式说明一个参数,该形参是运算符的右操作数。 (2) 前置单目运算符重载为类的成员函数时,不需要显式说明参数,即函数没有形参。 (3) 后置单目运算符重载为类的成员函数时,函数要带有一个整型形参。 调用成员函数运算符的格式如下: <对象名>.operator <运算符>(<参数>) 它等价于 <对象名><运算符><参数> 例如:a+b等价于a.operator +(b)。一般情况下,我们采用运算符的习惯表达方式。 友元函数运算符 运算符重载为类的友元函数的一般格式为: friend <函数类型> operator <运算符>(<参数表>) { <函数体> } 当运算符重载为类的友元函数时,由于没有隐含的this指针,因此操作数的个数没有变化,所有的操作数都必须通过函数的形参进行传递,函数的参数与操作数自左至右一一对应。 调用友元函数运算符的格式如下: operator <运算符>(<参数1>,<参数2>) 它等价于 <参数1><运算符><参数2> 例如:a+b等价于operator +(a,b)。 两种重载形式的比较 在多数情况下,将运算符重载为类的成员函数和类的友元函数都是可以的。但成员函数运算符与友元函数运算符也具有各自的一些特点: (1) 一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好重载为类的友元函数。 (2) 以下一些双目运算符不能重载为类的友元函数:=、()、[]、->。 (3) 类型转换函数只能定义为一个类的成员函数而不能定义为类的友元函数。 (4) 若一个运算符的操作需要修改对象的状态,选择重载为成员函数较好。 (5) 若运算符所需的操作数(尤其是第一个操作数)希望有隐式类型转换,则只能选用友元函数。 (6) 当运算符函数是一个成员函数时,最左边的操作数(或者只有最左边的操作数)必须是运算符类的一个类对象(或者是对该类对象的引用)。如果左边的操作数必须是一个不同类的对象,或者是一个内部类型的对象,该运算符函数必须作为一个友元函数来实现。 (7) 当需要重载运算符具有可交换性时,选择重载为友元函数。 Class CDigit { public: CDigit() { m_digit = 0; } CDigit(int digit):m_digit(digit){} CDigit(const CDigit& digit){ this->m_digit = digit.m_digit;} CDigit& operator=(const CDigit& digit) { this->m_digit = digit.m_digit; return *this; } CDigit& operator+(const CDigit& digit) { this->m_digit = this->m_digit + digit.m_digit; return *this; } CDigit& operator-(const CDigit& digit) { this->m_digit = this->m_digit - digit.m_digit; return *this; } CDigit& operator+=(const CDigit& digit) { this->m_digit = this->m_digit + digit.m_digit; return *this; } friend ostream& operator<<(ostream& os,CDigit& digit); friend istream& operator>>(ostream& is,CDigit& digit); friend bool operator==(CDigit& digit,CDigit& digti2); //自增自减 CDigit& operator++() { this->m_digit ++; return *this; } CDigit operator++(int) { CDigit old(*this); ++(*this); return old; } private: int m_digit; }; |
|
来自: dongtongtong > 《C Primer(第五版)》