44348


c++の参考書で「friend関数はthisポインタを持たない、そのクラスに所属しているわけではない、非公開メンバにアクセスできる。  
タイトル通り friend関数とfriendクラスの違いについて教えて欲しいです。

[code]

    int main(){
        Date a(4),b(3);
        Date c = test(a,b);
    }
    
    class Date {
    
    private:        
        //double d;
        int x;
        int z;
        static int prst;//静的記憶域期間
    
    public:
        Date();
    
        Date(int x);
    
        void print();
        //////////////////////////////////
        friend  Date test(const Date& a, const Date& b)//friend関数
        {
            return Date(a.x + b.x);
        }
        //////////////////////////////////
        int y = 0;
        static int pust;//静的記憶域期間
    
        void pri(int x);
        static void pri_st(int x);
    };
    
[/code]


CC BY-SA 4.0
2018-05-27T11:47:18.337
44299
2018-05-29T02:35:31.627
2018-05-28T07:10:31.087
19110
question
c++
c++ friend関数とfriendクラスの違いを知りたいです。


まず、friend関数とfriendクラスの違いは関数とクラスの違いだけです。  
ところで、当初の質問内容はfriendの意味だったと思うのですが、それも一般的な回答は検索で見つかると思います。

さて、大昔の自分もfriendの利用シーンがなかなか思いつかなかったのですが現在は下に述べる部分で使用しています。

(1)friend関数の利用シーン  
OSないしシステム側がコールバック関数(C言語の関数)を要求する場合に、直接クラスメンバ関数を渡せないのでfriend関数に橋渡しをしてもらう場合等に使ってます。

(2)friendクラスの利用シーン  
非公開のコンストラクタ(デストラクタ)しか持たないクラスAが、Aの配列クラス等に生殺与奪を任せたい場合等に使ってます。派生させればどこでも構築できてしまう場合もありますが、それをやってはいけませんという意味を表現しているつもりです。

以上、具体的な事例もなんらかの役にたつかもしれませんので経験上の一例をあげてみました。


CC BY-SA 4.0
2018-05-29T02:26:50.693
44345
2018-05-29T02:32:03.523
2018-05-29T02:32:03.523
3793
3793
44299
answer


書かれているとおり `friend` 関数は「非メンバなのに `private` `protected`
なメンバを直接使うことを認める」ためのものです。適切に OOAD (Object-Oriented Analysis and Design)
ができていればまず使うことは無い / 使う必要が無いものです。  
使うとしたら「非メンバ関数」として実装するしか手が無い関数を使う場合とか。

自作複素数クラス `class mycomplex` を実装して `double + mycomplex`
ができるような演算子を実装したくなったら、左辺が組み込み型なので非メンバ関数な `operator+` が必要となり

[code]

    class mycomplex {
        double re; // real part
        double im; // imaginary part
    public:
        mycomplex(double r0=0.0, double i0=0.0) : re(r0), im(i0) { }
        mycomplex(const mycomplex& rh) : re(rh.re), im(rh.im) { }
        // double + mycomplex を行う非メンバ関数 (static メンバでもない)
        friend mycomplex operator+(double lh, const mycomplex& rh) {
            return mycomplex(lh+rh.re, rh.im);
        }
        // 普通に (non-static な) メンバ関数 mycomplex+mycomplex
        mycomplex operator+(const mycomplex& rh) const {
            return mycomplex(this->re+rh.re, this->im+rh.im);
        }
    };
    
[/code]

こんな形で「非メンバな関数」の中で `private` なメンバを直に使うことができます（この `mycomplex` 中で `re` や `im` が
`private` としていることが適切かどうかはまた別問題なのでいまはおいておく）  
# そうしている意図は、将来、内部実装を極座標表示にするかもってことなわけだけど

`operator` 以外であっても、フレームワークやライブラリの実装上の都合で非メンバ関数を使わざるを得ないような場合に `friend`
関数を使うことがあるでしょう。  
[class メンバー関数をコールバックとして渡したい](https://ja.stackoverflow.com/questions/36847/)

組み込み系だと、開発ツールが割り込みハンドラを [c](/questions/tagged/c "'c' のタグが付いた質問を表示")
関数として自動生成してしまったりするので `friend` 関数の出番がままあったりします。

`friend` クラスのほうは「使ったら設計ないしは実装に失敗している」レベルで使い道が無くて、オイラも実用したことはありません。

`friend` は `class`
が隠している内面をもろにさらけ出す（オイラは｢臓物を晒す」と称しています）ので、必要の無いところで使うことは禁じ手です。逆に、必要ならためらい無く使いましょう。そういう機能があればより性能が出せるという場面では、あぶない機能でも使えるというのが
[c](/questions/tagged/c "'c' のタグが付いた質問を表示") や [c++](/questions/tagged/c%2b%2b
"'c++' のタグが付いた質問を表示") の言語設計方針なので、取捨選択するのはユーザの責任です。


CC BY-SA 4.0
2018-05-29T02:35:31.627
44348
2018-05-29T02:35:31.627
8589
44299
answer