0

MainScheduler のメソッド addJob を Job クラスのフレンド関数にしようとしています。

#include "MainScheduler.h"
//forward declaration
class MainScheduler;

class Job:
{
    friend void MainScheduler::addJob( Job* const job );
    ...
}

しかし、私はエラーが発生し続けます

エラー C2027: 未定義の型 'MainScheduler' の使用

このメッセージが表示される理由と、修正方法を教えてください。

4

2 に答える 2

5

フレンドシップ宣言であっても、既に宣言されているメンバー関数にのみ名前を付けることができます。これは、前方宣言だけでなく、クラスを定義する必要があることを意味します。

違う:

class X;

class Y
{
    friend void X::f(); // ERROR
};

右:

class X
{
public:
    void f();
};

class Y
{
    friend void X::f();
};

#include "MainScheduler.h"可視化の定義を作成しなかった理由は明らかではないため、class MainScheduler別の奇妙なことが起こっています。

このルールは、 is a friendやis a friend A::f()of のようなことを行うことができないことを意味するため、クラス全体を友だちにすることで解決する必要がある場合もあります。(または、ヘルパー クラスを使用して特定の関数セットのアクセス許可を要求/付与する優れた方法がありますが、拡張可能なライブラリ インターフェイスが必要な場合には、より便利です。)BB::g()A

于 2012-06-02T17:06:25.970 に答える
2

問題は非常に単純です。依存関係のサイクルを持つことはできません。

// MainScheduler.h
#ifndef MAINSCHEDULER
#define MAINSCHEDULER

#include "Job.h"

class MainScheduler { friend class Job; };

#endif


// Job.h
#ifndef JOB
#define JOB

#include "MainScheduler.h"

class Job { friend class MainScheduler; };

#endif

MainScheduler.h を解析すると、次のようになります。

  • MAINSCHEDULERは定義されていないため、解析が開始されます
  • プリプロセッサが定義するMAINSCHEDULER
  • プリプロセッサには Job.h が含まれています
  • は既に定義されているためMAINSCHEDULER、MainScheduler.h のインクルードをスキップします。
  • からのトークンが含まれますJob
  • Job.h のインクルード終了
  • からのトークンが含まれますMainScheduler

これにより、コンパイラが確認する次のプリプロセッサ出力が生成されます。

// ignored #include "MainScheduler.h"

class Job { friend class MainScheduler; };

class MainScheduler { friend class Job; };

MainSchedulerこれが、前方宣言を導入する前に、コンパイラが の定義にある不明なシンボルについて不平を言った理由ですJob

ヘッダー自体をサイクルに含めることはできません。また、前方宣言のみでメンバー関数と友達になることはできません。

Job.h を次のように書き換えることをお勧めします。

class MainScheduler; // forward declaration

class Job {
    friend class MainScheduler;
public:
    // whatever

};

クラス全体と仲良くなることで、前向きな宣言だけで逃げ出し、サイクルを断ち切ることができます。

于 2012-06-02T17:21:34.917 に答える