對c++友元函式和友元類的理解
1,友元函式的定義和作用
我們已知道類具有封裝和資訊隱藏的特性。只有類的成員函式才能訪問類的私有成員,程式中的其他函式是無法訪問私有成員的。非成員函式可以訪問類中的公有成員,但是如果將資料成員都定義為公有的,這又破壞了隱藏的特性。另外,應該看到在某些情況下,特別是在對某些成員函式多次呼叫時,由於引數傳遞,型別檢查和安全性檢查等都需要時間開銷,而影響程式的執行效率。
為了解決上述問題,提出一種使用友元的方案。友元是一種定義在類外部的普通函式,但它需要在類體內進行說明,為了與該類的成員函式加以區別,在說明時前面加以關鍵字friend。友元不是成員函式,但是它可以訪問類中的私有成員。友元的作用在於提高程式的執行效率(即減少了型別檢查和安全性檢查等都需要的時間開銷),但是,它破壞了類的封裝性和隱藏性,使得非成員函式可以訪問類的私有成員。
為什麼不能直接訪問呢?
先了解一下為什麼成員函式可以直接訪問成員變數?
成員函式能夠訪問類的成員變數是因為傳遞了指向當前物件的this指標,它如果訪問資料成員對其操作是this指向的物件的資料成員,是有實際意義的 。
友元函式不是成員函式,沒有傳遞隱藏的this指標,只能間接訪問。
這點其實和靜態成員函式一樣,靜態成員函式也是沒有this指標的,所以它只能訪問靜態成員變數或者通過物件訪問非靜態成員變數。
例子:
3,類和類之間的友元關係不能繼承。class Rect { public: Rect() // 建構函式,計數器加1 { count++; } //Rect(const Rect& r) //{ // width = r.width; // height = r.height; // count++; //} ~Rect() // 解構函式,計數器減1 { count--; } static int getCount() // 返回計數器的值 { return count; } friend int get(); private: int width; int height; static int count; // 一靜態成員做為計數器 }; int Rect::count = 0; // 初始化計數器 int get() { return Rect::count;//友元函式通過類訪問私有靜態成員變數 } int main() { Rect rect1; cout<<"The count of Rect: "<<Rect::getCount()<<endl;//通過類訪問公有靜態成員函式,輸出1 Rect rect2(rect1); // 使用rect1複製rect2,此時應該有兩個物件 cout<<"The count of Rect: "<<Rect::getCount()<<endl; //輸出1 cout << get() << endl;//輸出1 //cout << Rect::count << endl;//不能編譯通過,不能訪問私有成員 system("pause"); return 0; }
下邊轉載自:
http://blog.csdn.net/shandianling/article/details/7469361
C++ Primer中有如下描述:友元關係不能繼承。基類的友元對派生類的成員沒有特殊訪問
許可權。如果基類被授予友元關係,則只有基類具有特殊訪問許可權,該基類的派生類不能訪問授予友元關係的類。
然而通過實踐發現,VS編譯器並沒有安裝上述描述來處理,下面的規則與上述描述相悖,卻符合VS編譯器的處理規則。
注:有待通過g++編譯器來驗證。
1 友元類的繼承問題
1.1 A類的友元B的派生類C 不能訪問A類的private或protect成員變數。但可以通過B提供的介面來訪問A。(廢話肯定可以)
- #include <iostream>
- usingnamespace std;
- class B;
- class A
- {
- int a;
- public:
- A(int x=0) { a=x; }
- friendclass B;
- };
- class B
- {
- int b;
- public:
- void fun(A& ob){ cout << ob.a << endl;}
- };
- class C:public B
- {
- public:
- //void fun2(A& ob){ cout <<ob.a <<endl;} //派生類新加的函式卻不能訪問A,此句會報錯
- };
- void main()
- {
- A a(55);
- C c;
- c.fun(a); //C是B的派生類 通過基類B的函式fun仍然可以訪問
- }
1.2. Base的友元可以通過Base的派生類Drived訪問Base的private,protect成員變數,但不能訪問Drived的private,protect成員變數。(這一點似乎與《C++ primer》裡說的有點衝突)
個人理解:Drived的物件本身就包含Base,Base的友元Frnd自然就可以訪問Base的部分。
- #include <iostream>
- usingnamespace std;
- class Base
- {
- int m_a;
- public:
- Base(int x=0){ m_a=x; }
- friendclass Frnd;
- };
- class Drived:public Base
- {
- private:
- int m_c;
- public:
- Drived(int x):Base(x){m_c=x;}
- };
- class Frnd
- {
- public:
- void fun(Base& ob) { cout <<ob.m_a << endl; }
- void fun2(Drived& ob)
- {
- cout << ob.m_a<<endl;
- //cout <<ob.m_c<<endl; //編譯錯誤
- }
- };
- int main()
- {
- Drived d(1);
- Frnd f;
- f.fun(d);
- f.fun2(d);
- system("pause");
- return 0;
- }
3 友元類的傳遞問題
A的友元是B,B的友元是C,那A的友元是C? 不是,友元類不具有傳遞性。
相關推薦
對c++友元函式和友元類的理解
1,友元函式的定義和作用 我們已知道類具有封裝和資訊隱藏的特性。只有類的成員函式才能訪問類的私有成員,程式中的其他函式是無法訪問私有成員的。非成員函式可以訪問類中的公有成員,但是如果將資料成員都定義為公有的,這又破壞了隱藏的特性。另外,應該看到在某些情況下,特別是在對某
c++之友元函式和友元類
c++友元函式一些見解 1、為什麼要引入友元函式:在實現類之間資料共享時,減少系統開銷,提高效率 具體來說:為了使其他類的成員函式直接訪問該類的私有變數 即:允許外面的類或函式去訪問類的私有變數和保護變數,從而使兩個類共享同一函式 優點:能夠提高效率,表達簡單、清晰
C++友元函式和友元類用法詳解
在C++中,我們使用類對資料進行了隱藏和封裝,類的資料成員一般都定義為私有成員,成員函式一般都定義為公有的,以此提供類與外界的通訊介面。但是,有時需要定義一些函式,這些函式不是類的一部分,但又需要頻繁地訪問類的資料成員,這時可以將這些函式定義為該函式的友元函式。除了友元函式
C++友元函式和友元類(C++ friend)詳解
私有成員只能在類的成員函式內部訪問,如果想在別處訪問物件的私有成員,只能通過類提供的介面(成員函式)間接地進行。這固然能夠帶來資料
C++過載(2):通過成員函式和友元函式過載
分別通過成員函式和友元函式完成過載 #include <iostream> using namespace std; class Complex { public: Complex(double real =0,double imag=0):real(real),imag(i
友元(友元函式、友元類和友元成員函式) C++
有些情況下,允許特定的非成員函式訪問一個類的私有成員,同時仍阻止一般的訪問,這是很方便做到的。例如被過載的操作符,如輸入或輸出操作符,經常需要訪問類的私有資料成員。 友元(frend)機制允許一個類將對其非公有成員的訪問權授予指定的函式或者類
C++實現輸入輸出運算子過載、友元函式和成員函式實現複數類Complex
今天答應幫朋友做一個C++題目,頗費了一番周折,終於還是寫出來了,讓很久沒敲程式碼的我反省了一下,也回憶了以前學過的知識。 題目要求如下: 一、按下列要求編制複數類,並除錯通過: 1) 基本的建構函式; 2) 成員運算子+、-實現複數的加減運算; 3) 友元運算子+
採用成員函式和友元函式計算給定兩個座標點之間的距離
設計一個用來表示直角座標系的Location類,在主程式中建立類Location的兩個物件A和B,要求A的座標點在第3象限,B的座標點在第2象限,分別採用成員函式和友元函式計算給定兩個座標點之間的距離,要求按如下格式輸出結果: A(x1,y1), B(x2,y2), Distance1=d1
c++成員運算子過載和友元運算子過載的比較(以++,--運算子為例)
1、對雙目運算子而言,成員運算子過載函式引數列表中含有一個引數,而友元運算子過載函式引數列表含有兩個引數;對單目運算子而言,成員運算子過載函式引數列表中沒有引數,而友元運算子過載函式引數列表含有一個引數。 2、雙目運算子一班可以被過載為友元運算子和成員函式運算
成員函式和友元函式完成二元運算子過載
傳智掃地僧課程學習筆記。 運算子過載實現方法, 1,用成員函式 2,用友元函式 區別是,傳參是否內部使用this指標, 全域性函式、類成員函式方法實現運算子過載步驟 1)要承認操作符過載是一個函式,寫出函式名稱operator+ ()
成員函式和友元函式 完成二元和一元運算子過載(進階1)
二元運算子過載: 全域性函式: #include <iostream> using namespace std; class Complex{//複數類 private: int
C++學習筆記(10)運算子過載,友元函式,友元類
c++允許我們為運算子定義專門的函式,這被稱為運算子過載: 運算子可以簡化字串的操作,‘+’,以及使用關係運算符比較字串,[ ]運算子訪問向量中的元素; 例如: #include <iostream> #include <string> #include <
成員函式和友元函式實現一元運算子過載
使用友元函式實現一元運算子的過載 實現一元運算子的前置過載 即前置++a; #include <iostream> using namespace std; class Comple
C++模板類內友元(友元函式,友元類)宣告的三種情況
根據《C++ Primer》第三版16.4節的敘述,C++類模板友元分為以下幾種情況1.非模板友元類或友元函式。 書上給了一個例子:class Foo{ void bar();};template <class T>class QueueItem{
運算子過載函式作為類成員函式和友元函式
作為類成員函式的例子: #include <iostream> using namespace std; class Complex{ public: Complex(){real = 0; imag = 0;} Complex(double r
“friend宣告友元函式,友元函式卻依舊無法訪問該類的私有屬性”的解決方法
“friend宣告友元函式,友元函式卻依舊無法訪問該類的私有屬性”的解決 一次C++作業題, 搞了很久弄明白了, 雖然成功了, 但VS2015依舊有紅線提示錯誤, 不過不影響編譯、執行, 這似乎是VS
友元函式與友元類的宣告與使用
1.友元函式的簡單介紹 1.1為什麼要使用友元函式 在實現類之間資料共享時,減少系統開銷,提高效率。如果類A中的函式要訪問類B中的成員(例如:智慧指標類的實現),那麼類A中該函式要是類B的友元函式。具體來說:為了 使其他類的成員函式直接訪問該類的私有變數。即:允許外
c語言對時間的處理函式和計時的實現
關鍵字:c語言 時間函式 time.h c語言時間函式,時間頭函式 所有程式碼編譯環境:MSVC6.0 1,時間的獲取: 通過time()函式來獲得日曆時間(Calendar Time),其原型為:time_t time(time_t * timer); #incl
C++中對純虛擬函式和多型的理解
抽象類是一種特殊的類,它是為了抽象和設計的目的為建立的,它處於繼承層次結構的較上層。 ⑴抽象類的定義: 稱帶有純虛擬函式的類為抽象類。 ⑵抽象類的作用: 抽象類的主要作用是將有關的操作作為結果介面組織在
C++ string成員函式和cstring庫函式
首先是C字串: C 庫函式 - strcmp() 比較2個C字串的字典序大小 描述 C 庫函式 int strcmp(const char *str1, const char *str2) 把 str1 所指向的字