C++学习笔记15:流插入运算符和流提取运算符的重载

流插入运算符的重载
问题

        问题1:cout << 5 << "this";    为什么该语句可以成立?
        问题2:cout是什么?    “<<”为什么能用在cout上?

解答

        cout是在iostream中定义的,ostream类的对象
        “<<”能够用在cout上面,因为在iostream里对“<<”进行了重载
    考虑
        如何重载才能使得 cout << 5; 和 cout << "this"都成立?
    方案
        1 重载成ostream类的成员函数
            void ostream::operator<<(int n)
            {
                ....    // 输出n的代码
                return;
            }
        2 cout << 5;    即 cout.operator<<(5);
          cout << "this"; 即 cout.operator<<(“this”);
        3 如何重载才能使得以下成立:
            cout << 5 << "this";
            分析:cout左移5的返回值还是cout,就可以继续往下运算
            则运算符<<重载方式如下
            ostream& ostream::operator<<(int n)
            {
                ......  // 输出n的代码
                return *this;  // this指针指向成员函数所作用的对象,如果执行cout << 5,则this指针指向cout,*this就是cout,则函数返回值是cout的引用。
            }
            ostream& ostream::operator<<(const char* s)
            {
                ....    // 输出s的代码
                return *this;
            }

            则cout << 5 << "this";本质上的函数调用如下:
                cout.operator<<(5).operator<<("this");
    假定一下程序输出为5hello,该做些什么?(见本工程student.cpp)
//
// 流插入运算符的重载例子
//

#include 

using namespace std;

class CStudent{
public:
    int nAge;
};

// 运算符 << 重载为全局函数  参数2取为CStudent的引用节省时间和空间,不需要生成形参对象,因为形参对象需要调用复制构造函数,有开销。
// 参数1  节省开销 也选择了ostream的引用  如果不选择ostream的引用,则编译出错。原因时形参与实参的差别
ostream& operator<<(ostream& o, const CStudent& s)
{
    o << s.nAge;
    return o;   // 因为参数1 o是cout的引用  所以直接返回o即可。
}

int main()
{
    CStudent s;
    s.nAge = 5;
    // 此处需要重载流插入运算符<<  由于ostream已经定义好的,因此只能重载为全局函数
    cout << s << "hello";
    return 0;
}

        class CStudent{
            public:
                int nAge;
        };
        int main()
        {
            CStudent s;
            s.nAge = 5;
            cout << s << "hello";
            return 0;
        }

流提取运算符的重载
    例题:
        题目:假定c是Complex复数类的对象,现在希望写“cout << c;” 就能以“a + bi”的形式输出c的值,写“cin >> c;”就能从键盘接收“a + bi”形式的输入,并且使得c.real = a, c.imag = b;
        答案:(见本项目complexcin.cpp)
//
// 题目:假定c是Complex复数类的对象,现在希望写“cout << c;” 就能以“a + bi”的形式输出c的值,写“cin >> c;”就能从键盘接收“a + bi”形式的输入,并且使得c.real = a, c.imag = b;
//
#include 

using namespace std;

class Complex{
private:
    double real; double imag;
public:
    Complex(double r = 0, double i = 0):real(r),imag(i){}
    // 全局函数需要访问类Complex的私有成员,因此需要声明友元形式
    friend ostream& operator<<(ostream& o, const Complex& c );
    friend istream& operator >> (istream& i, Complex& c);
};

ostream& operator<<(ostream& o, const Complex& c ){
    o << c.real << " + " << c.imag << "i ";
    return o;
}

// 学习完string类之后回头来看。
istream& operator >> (istream& i, Complex& c){
    string s;
    i >> s; // 将“a + bi”作为字符串读入,“a+bi”中间不能有空格
    int pos = s.find("+",0);
    string sTmp = s.substr(0,pos);  //分离处代表实部的字符串
    c.real = atof(sTmp.c_str());
    // atof库函数能够将const char*指针指向的内容转换
    sTmp = s.substr(pos + 1, s.length()-pos-2);
    // 分离处代表虚部的字符串
    c.imag = atof(sTmp.c_str());
    return i;
}

/**
 * 程序运行结果可以是:
 *      键盘输入 13.2 + 133i 87
 *      13.2 + 133i 87
 * */
int main()
{

    Complex c;
    int n;
    // 需要重载 >> 运算符
    cin >> c >> n;

    // 需要重载 << 运算符  使用全局函数
    cout << c << n;

    return 0;
}

你可能感兴趣的:(C++)