C++友元関数の関数ポインタ

1880 ワード

メンバー関数のポインタ
友元を話す前に普通のメンバー関数の関数ポインタを話します
class Std_interface {
public:
    virtual void suspend() = 0;
};

// define the pointer of function
typedef void (Std_interface::* Pstd_mem) ()

void f(Std_interface* p) {
    Pstd_mem s = &Std_interface::suspend;

    // call directly
    p->suspend();

    // by pointer
    (p->*s)();
}

関数ポインタがクラスメンバーオブジェクトを指す場合、関数ポインタの定義にクラス名と:(役割ドメイン演算子)関数ポインタがどのクラスのメンバー関数を指すかを識別する必要があります.
関数ポインタが指すクラスメンバー関数を呼び出す場合は、メンバー関数のアクセスと同様に、関数が操作するクラスオブジェクトを指定し、このオブジェクトでこの関数を呼び出す必要があります.
ゆうげんかんすう
では、関数ポインタが通常の関数ポインタとして宣言されている場合、解決策はありますか?友元関数を使用してstatic関数と同じ特性は次のとおりです.
  • 関数
  • をアクティブにするには、thisポインタを提供する必要はありません.
  • クラスにアクセス可能なプライベートメンバー
  • 違いは、この関数がクラスの役割ドメインに含まれていないことです.次のコードを分析します.
    // GlAnimator.h
    class GlAnimator {
    public:
        int example();
        friend int LoopInThread(GlAnimator *animator_ptr);
    };
    
    // GlAnimator.cpp
    typedef int(*InnerLoop)(GlAnimator *);
    
    int GlAnimator::example() {
        InnerLoop inner_loop = &LoopInThread;
        return 0;
    }
    // friend function
    int LoopInThread(GlAnimator *animator_ptr) {
        // ...
        return 0;
    }
    InnerLoop inner_loop = &LoopInThread;箇所が間違っていて、「LoopInThread undeclared」と言うのは面白いですが、ヘッダファイルで定義されているのに!なぜなら、上記の役割ドメインがクラス内にないのに、メンバー関数example()でアドレスを取りに行った場合、明らかに宣言されていないからです.
    解決策はもう一度宣言して、全部で2回宣言して、関数のポインタを取る前に宣言すればいいです.私はヘッダーファイルの中でするのが好きです.ヘッダーファイルの修正は以下の通りです.
    // GlAnimator.h
    class GlAnimator {
    public:
        int example();
        friend int LoopInThread(GlAnimator *animator_ptr);
    };
    
    // declare the friend function again
    int LoopInThread(GlAnimator *animator_ptr);

    参考資料
    http://www.cplusplus.com/forum/general/23265/
    http://hipercomer.blog.51cto.com/4415661/941682
    転載先:https://www.cnblogs.com/psklf/p/6490172.html