1. 程式人生 > >為什麼c++中過載流操作符要用友元函式

為什麼c++中過載流操作符要用友元函式

1.先來看看友元函式過載流操作符例項

class complex
{

public:

    complex(int x, int y): real(x), imag(y){}
    complex():complex(0,0){}
    ~complex(){}

    friend ostream& operator << (ostream& cout, complex& par);

private:

    int real;
    int imag;
    
}

ostream& operator << (ostream& cout, complex& par);
{
    cout << par.real << "+" << par.imag << "i" << endl;
    return cout;
}

2. 再來看看成員函式過載操作符例項

class complex
{

public:
    complex(int x, int y): real(x), imag(y){}
    complex():complex(0,0){}
    ~complex(){}

    complex operator + (complex par)
    {
        complex resault;
        resault.real = real + par.real;
        resault.imag = imag + par.imag;
        return resault;
    }

private:

    int real;
    int imag;

}

成員函式執行機理:

假如C1與C2d都為complex類,則,C1+C2被編譯系統解釋為C1.operator +(C2);

對比可以得到結論:

1. 實際上流操作符左側必須為cin或cout,即istream或ostream類,不是我們所能修改的類;或者說因為流操作符具有方向性。

這導致我們不能使用成員函式過載,只能使用類外的普通函式過載。

2. 由於我們將類內部的私有成員進行輸入和輸出,所以過載函式必須有對內部成員訪問的許可權。

這導致我們不能使用普通的函式過載,只能使用友元函式過載。

3. 好的解決方案

但是使用友元函式會破壞類的封裝性,因此好的解決方法是:

使用一些成員函式來暴露對類成員的訪問,然後使用類外的普通函式過載來進行類成員的輸入輸出。

程式碼如下:

class complex
{

public:

    complex(int x, int y): real(x), imag(y){}
    complex():complex(0,0){}
    ~complex(){}
    
    int getReal(){ return real;}    
    int getImag(){ return imag;}    
    void setReal(int parm){ real = parm;}    
    void setImag(int parm){ imag = parm;}    


private:

    int real;
    int imag;

}

ostream& operator << (ostream& cout, complex& par);
{
    cout << par.getReal() << " + " << par.getImag() << "i" << endl;
    return cout;
}

相關推薦

為什麼c++過載操作符函式

1.先來看看友元函式過載流操作符例項 class complex { public: complex(int x, int y): real(x), imag(y){} complex():complex(0,0){} ~complex(){}

(轉)為什麼operator運算子過載一定函式

如果是過載雙目操作符(即為類的成員函式),就只要設定一個引數作為右側運算量,而左側運算量就是物件本身 而 >> 或<< 左側運算量是 cin或cout 而不是物件本身,所以不滿足後面一點,就只能申明為友元函數了 如果一定要宣告為成員函式,只能成為如下的形式:

學生類,含學生姓名與成績,函式訪問私有成員,對兩個物件的成績進行比較。(2018.9.19 c++作業)

定義兩個物件,與一個友元函式(使用c++中引用傳遞的方式,實現引數的傳遞) #include using namespace std; class student { private: char name[20]; float grade; public: s

為什麼operator運算子過載一定函式呢?

格拉德韋爾在《異數》:並非天資超人一等,而是付出了持續不斷的努力。只要經過1萬小時的錘鍊,任何人都能從平凡變成超凡”。要成為某個領域的專家,需要10000小時:如果每天工作八個小時,一週工作五天,那麼成為一個領域的專家至少需要五年。 linux原始碼線上閱讀 各種線編譯工具

定義一個複數類,函式實現對雙目運算子“ + ”的運算子過載, 使其適用於複數運算

////定義一個複數類,用友元函式實現對雙目運算子“ + ”的運算子過載,////使其適用於複數運算//#include<iostream>using namespace std;class Complex{private:int real;int imag;pu

C++面向物件總結(二)--函式

類的友元函式 類的友元函式是定義在類外部,但有權訪問類的私有成員(private)和保護成員(protected)成員。儘管友元函式的原型在類的定義中出現過,但是友元函式並不是成員函式。#includ

C#如何利用操作符過載和轉換操作符 (轉載)

操作符過載 有的程式語言允許一個型別定義操作符應該如何操作型別的例項,比如string型別和int型別都過載了(==)和(+)等操作符,當編譯器發現兩個int型別的例項使用+操作符的時候,編譯器會生成把兩個整數加到一起的程式碼。當編譯器發現兩個string型別的例項使用+操作符的時候,編譯器會生成把兩個

C++的魅力之操作符過載,簡單的函式

1.簡單的友元函式 友元函式可以直接訪問private:中的資料。 我們一定要認識到一點,相同class的各個object互為friends(友元) 比如: class complex { public

C++學習筆記(七)--操作符過載 函式 類的繼承 訪問控釋protected

C++ Primer Plus的閱讀大概到這邊也就先暫時告一段落了(因為開學了!!) 然後近期找來了C++ Primer稍微翻了翻覺得確實寫得比Plus要好一些,而且加入了C++11的新特性,但是無論哪本書對於這些最基本的功能應用大抵也是差不多的,所以也沒覺得看的是Plu

C++賦值操作符為什麼返回引用型別

class Test {     Test& operator= (const Test& t)            {           } } 這個是我們熟悉的賦值操作符函式的格式,但是該函式為什麼非得要返回一個引用呢。 查閱了很多資料感覺這種解釋比

GUN C

文件 linux環境 函數 操作文件 文件操作 作文件 必須 連接 過程   當我們要對文件(在Linux環境中一切皆文件,包括硬件設備、資源等)進行操作(讀、寫、讀寫)時,必須連接文件或形成通信管道。這個過程稱為打開文件。打開文件後可以進行讀、寫、讀寫操作。   打開的文

C#事件的動態調實現方法

ear too new std 實現 bject multicast using pad 本文實例講述了C#動態調用事件的方法。一般來說,傳統的思路是,通過Reflection.EventInfo獲得事件的信息,然後使用GetRaiseMethod方法獲得事件被觸發後調用

C++placement new操作符

不足 滿足 緩存 內存泄露 tar 第二章 pcl 準備 垃圾收集 placement new是重載operator new的一個標準、全局的版本,它不能被自定義的版本代替(不像普通的operator new和operator delete能夠被替換成用戶自定義的版本)。

等號操作符重載為什麽不能函數大揭秘,以及函數沒有等到重載的時候賦值會出現什麽現象(盲點)

style 報錯 round 賦值運算符重載 -c post body opera 為什麽 先看下面程序結果輸出什麽? 1 #include <iostream> 2 using namespace std; 3 4 clas

C++過載(2):通過成員函式函式過載

分別通過成員函式和友元函式完成過載 #include <iostream> using namespace std; class Complex { public: Complex(double real =0,double imag=0):real(real),imag(i

fstream 判斷是否成功開啟檔案 | C++檔案(fstream)的使用方法及示例

ifstream fin("filename"); if (!fin) { cout << "fail to open the file" <<endl; return -1;//或者丟擲異常。 } else { cout << "open

關於C++的friend函式的總結

1.友元函式的簡單介紹 1.1為什麼要使用友元函式 在實現類之間資料共享時,減少系統開銷,提高效率。如果類A中的函式要訪問類B中的成員(例如:智慧指標類的實現),那麼類A中該函式要是類B的友元函式。 具體來說:為了使其他類的成員函式直接訪問該類的私有變數。即:允許外面的類或函式去訪問

函式過載操作符

當使用namespace std的時候會出現訪問不了私有成員的錯誤,不使用std便沒有錯誤。奇怪的是之前的程式使用的std也沒有錯誤,不知為何  #ifndef STRING_H_ #define STRING_H_ #include <iostream> //

C++過載、覆蓋和隱藏的區別,以及適用場景

一、過載、覆蓋和隱藏的區別 二、適用場景 1、過載:   適用於不同的資料型別都需要使用到的功能函式。以資料相加的函式為例,可以在同一個檔案內提供以下的過載函式以支援同樣的功能:   int add(int, int);/*2個整數相加*/   int add(int, int, int);/*3個整數相

C++過載,覆蓋,隱匿,函式多型

C++的多型特性是這門語言很重要的一個特性。 一、靜態多型:編譯器在編譯期間完成的,編譯器根據函式實參的型別(可能會進行隱式型別轉換),可推 斷出要呼叫那個函式,如果有對應的函式就呼叫該函式,否則出現編譯錯誤。 二、動態多型:在程式執行期間(非編譯期