-4

という名前TestAPIのクラスと という名前のクラスがあるとしUserAPIます。クラスのオブジェクトUserAPIが作成され、クラスのヘッダーに含まれTestAPIます。

現在、オブジェクトのインスタンスは、のインスタンスのUserAPIプライベート メンバー変数にアクセスできる必要がありますTestAPIが、特定のオブジェクトが作成されていないため、これは機能しません。ライブラリのユーザーにコード ( TestAPI) でオブジェクトを作成してもらいたいので、このオブジェクトは後で作成されます。

例:

main.cpp
{
    TestAPI test;
    test.User.SomeExampleToChangeRequest(); 
}

class TestAPI
{
    friend class UserAPI;
    public:
        UserAPI User;

    private:
        HINTERNET _hRequest;    // Variable which needs to be accessed from User    
};

リクエストハンドルを変更するクラス UserAPI のメソッド

UserAPI::SomeExampleToChangeRequest ()
{
    // how do I access _hRequest now? 
    // TestAPI._hRequest will not work since it's not static and class "global"
}

どうすればこれを実行できますか? これを友人として定義すると、アクセス許可に対してのみ機能し、私の問題は解決しません。

4

3 に答える 3

1

C++ を使用したオブジェクト指向設計の理解には、主に 2 つの改善点があります。

  • プライベート メンバーへのアクセスを提供する最初の選択肢は、 ではなく、パブリック メソッドにする必要がありfriendます。
  • メソッドで別の型のオブジェクトにアクセスするには、その型のオブジェクトを渡す必要があります。本当に必要な場合を除き、静的オブジェクトまたはグローバル オブジェクトについて考え始めないでください。

以下にいくつかのコードスニペットを掲載しました。それらを組み合わせて問題を解決してください。

class TestAPI {
public:
    // method to modify _hRequest
    void set_hRequest(HINTERNET& in_hRequest) {
        _hRequest = in_hRequest;
    }

    // method to access _hRequest
    HINTERNET& get_hRequest() {
        return _hRequest;
    }

private:
    HINTERNET _hRequest;
};

.

UserAPI::SomeExampleToChangeRequest(TestAPI& t) {
    // use 't' to access TestAPI here, like so ...
    HINTERNET h = t.get_hRequest();  
}

ユーザーがオブジェクトを作成したら、参照によってメソッドTestAPIに渡すようにします。UserAPI::SomeExampleToChangeRequest()さらに、コンパイラを支援するために、gbjbaanb で言及されているように前方宣言を使用します。

于 2013-10-21T13:40:34.110 に答える
0

これがすぐに使用できない理由を説明するより明確な方法は、UserAPI の各インスタンスが、それがどこで作成されたのか、または何のために作成されたのかがわからないということだと思います。

正直なところ、このような直接リンクでは、UserAPI が _hRequest メソッドを呼び出せるように構築されるときに、ある種の「親」TestAPI ポインター/参照を UserAPI に提供する必要がある場合があります。

編集:

基本的に、UserAPI の定義を以下のように変更します。

// Forward declaration
class TestAPI;

class UserAPI
{
public:

    UserAPI( TestAPI* inParent )
    : m_parent ( inParent )
    {}

private:

    // Let's make this private to force construction with a TestAPI parent
    UserAPI(){}

    TestAPI* m_parent;
};

コンパイラはこれが存在することを知る必要があるため、前方宣言に注意してください。ヘッダー ファイルを使用している場合は、この宣言を userAPI.h の先頭に置き、userAPI.cpp に testAPI.h のみを含めます。

これにより、userAPI.h 内から TestAPI 関数を呼び出すことはできなくなりますが、userAPI.cpp 内では完全なアクセスが可能になることに注意してください。

その結果UserAPI::SomeExampleToChangeRequest、userAPI.cpp で定義する必要があります。

UserAPI::SomeExampleToChangeRequest ()
{
    // The TestAPI variable or function can now be accessed like so
    m_parent->_hRequest;
}

UserAPI::SomeExampleToChangeRequest最後の注意: 別のヘッダー ファイルと cpp ファイルを使用したくない場合は、TestAPI の定義の後に定義する限り、問題ありません。

最後の注意: Happy が述べたように、フレンドは実際には必要なく、オブジェクト指向 C++ では控えめに使用する必要があります。そのパラメータにアクセスするパブリック関数を作成することが望ましいでしょう

于 2013-10-21T09:58:29.817 に答える
0

前方宣言を作成できます。これは、「この定義は後で提供されます」と言う方法であるため、コードは正しく構文チェックされ、コンパイラーは後で物事を整理します (両方のクラスの完全な定義を知っています)。 .

ただし、制限があります。コンパイラは前方宣言されたクラスについて何も知らないため、そのメソッドやサイズを参照することはできません。これは、ポインターを介して参照する必要がほとんどあることを意味します。これをスマート ポインターでラップすることをお勧めします。

于 2013-10-21T13:22:23.580 に答える