閱讀467 返回首頁    go 阿裏雲 go 技術社區[雲棲]


c++學習筆記之類模板中的友元聲明

類模板中出現3種友元聲明,每一種友元聲明了與一個或者多個實體的友元關係
(1)普通非模板類或函數的友元聲明,將友元關係授予明確指定的類或函數。
(2)類模板或函數模板的友元聲明,授予對友元所有實例的訪問權。
(3)隻授予對類模板或函數模板的特定實例的訪問權的友元聲明。
1 普通友元

非模板類或非模板函數可以是類模板的友元。

#include <iostream>
using namespace std;

template <class Type> class Bar{
    //普通非模版類
    friend class FooBar;
    //普通非模版函數
    friend void fun();
    private:
        Type data;
    public:
        void setData(Type temp){
            data = temp;
        }
};

class FooBar{
    public:
        //非模版類成員可以訪問Bar類實例的任意成員
        void print(){
            Bar<int> bari;
            bari.setData(5);
            cout<<"data:"<<bari.data<<endl;

            Bar<string> bars;
            bars.setData("No");
            cout<<"data:"<<bars.data<<endl;
        }
};
//非模版函數可以訪問Bar類實例的任意成員
void fun(){
    Bar<int> bari;
    bari.setData(4);
    cout<<"data:"<<bari.data<<endl;

    Bar<string> bars;
    bars.setData("Yes");
    cout<<"data:"<<bars.data<<endl;
}

int main(){
    fun();

    FooBar fooBar;
    fooBar.print();

    return 0;
}

以上代碼說明FooBar的成員和fun函數可以訪問Bar類的任意實例的private成員和protected成員

2 一般模版友元關係
友元可以是類模版或者函數模版

#include <iostream>
using namespace std;

template <class Type> class Bar{
    //模版類
    template <class T> friend class FooBar;
    //模版函數
    template <class T> friend void fun(const Bar<T>&);
    private:
        Type data;
    public:
        void setData(Type temp){
            data = temp;
        }
};

template <class T> class FooBar{
    public:
        //模版類成員可以訪問Bar類實例的任意成員
        template <class U> void print(Bar<U> &bar){
            cout<<"模版類:"<<bar.data<<endl;
        }
};

//模版函數可以訪問Bar類實例的任意成員
template <class T> void fun(const Bar<T> &bar){
    cout<<"模版函數:"<<bar.data<<endl;
}

int main(){
    Bar<int> bari;
    bari.setData(4);

    Bar<string> bars;
    bars.setData("Yes");

    fun(bari);
    fun(bars);

    FooBar<int> fooBari;
    FooBar<string> fooBars;

    fooBari.print(bari);
    fooBars.print(bars);
    return 0;
}

一般模板友元關係:FooBar的任意實例都可以訪問Bar的任意實例的私有成員。fun函數相同。

3 特定的模版友元
除了將一個模版的實例設為友元,類也可以隻授予對特定實例的訪問權。

#include <iostream>
using namespace std;

//模版聲明
template <class T> class Bar;
template <class T> class FooBar;
template <class T> void fun(const Bar<T>&);

template <class Type> class Bar{
    //模版類特定實例
    friend class FooBar<int>;
    //模版函數特定實例
    friend void fun<int>(const Bar<int>&);
    private:
        Type data;
    public:
        void setData(Type temp){
            data = temp;
        }
};

template <class T> class FooBar{
    public:
        template <class U> void print(Bar<U> &bar){
            cout<<"模版類:"<<bar.data<<endl;
        }
};

template <class T> void fun(const Bar<T> &bar){
    cout<<"模版函數:"<<bar.data<<endl;
}

int main(){
    Bar<int> bari;
    bari.setData(4);

    Bar<string> bars;
    bars.setData("Yes");

    fun(bari);
    //fun(bars);   error:Type data is private

    FooBar<int> fooBari;
    FooBar<string> fooBars;

    fooBari.print(bari);
    //fooBars.print(bars); error:Type data is private
    return 0;
}


最後更新:2017-04-03 12:56:23

  上一篇:go 我在Github上的flare-spark項目
  下一篇:go 麵試經之海量用戶積分排名算法探討