0

わかりましたので、私は複数のプラットフォーム用にプログラミングすることを学んでいます。多くのインクルード/ライブラリがマクロを使用して、特定のプラットフォームで呼び出す関数をコンパイラに指示するのを見ました。

そこで、次のように定義しました。

#if defined _WIN32 || defined _WIN64
    #define Close(Handle) CloseHandle(Handle)
#else
    #define Close(Handle) close(Handle)
#endif

しかし、私の Socket クラスには次のメンバー関数があります。

Socket::Close()
{
    //Close socket and clean up..
}

私が次のことをするとき:

Socket sock(Port, LocalHost);
sock.Close();

私は得る:

error: 'class Socket' has no member named 'CloseHandle'
     #define Close(Handle) CloseHandle(Handle)
                           ^
note: in expansion of macro 'Close'
       sock.Close();
            ^

どうすれば修正できるのでしょうか、それとも Close を取り除いて typedef にするべきでしょうか?

4

2 に答える 2

2

最も簡単な解決策は、マクロに別の名前を使用することです。

しかし、それは正しいことではありません。一部のプラットフォームでは、プラットフォーム固有のアクションを実行するために、より複雑なロジックが必要になる場合があります (たとえば、「閉じる」の前に「フラッシュ」などを実行する必要がある場合があります)。したがって#ifdef、関数内を分離することをお勧めします。

void Close(Handle handle) {
#if defined _WIN32 || defined _WIN64
    CloseHandle(handle);
#else
    close(handle);
#endif
}

Socket::Close()
{
    //Close socket and clean up..
    ::Close(...);
}

Environmentすべてのシステム固有のアクションへのインターフェースを提供する抽象クラス ( ) を定義し、具体的なプラットフォームごとに (サブクラス - WindowsEnvironment、 で) クラスの実装を作成すると、さらに洗練されたものになります。PosixEnvironmentクラスのインスタンスは、グローバルにアクセス可能なシングルトンにすることができ、適切な環境の選択は、マクロをまったく使用せずに実行できます。プロジェクトで適切なソース ファイルをコンパイルするだけです。

于 2013-05-26T18:45:00.933 に答える
0

クラスのクロスプラットフォーム インターフェイスを作成する必要があります。たとえば、close()メソッドを作成する必要があります。このメソッドは、すべてのプラットフォームに存在する必要があります。プラットフォームごとに実装が異なる場合は、マクロを使用して、プラットフォームごとに個別の実装を追加する必要があります。ファイルで行う必要がありcppます。

.hファイル:

void close(Handle handle);

.cppファイル:

void Socket::close(Handle handle) {
  #if defined _WIN32 || defined _WIN64
    CloseHandle(handle);
  #else
    close(handle);
  #endif
}
于 2013-05-26T18:35:08.330 に答える