6

仮想継承と多重継承に関する以前の質問(クロスプラットフォームシナリオ)に続くために-いくつかの回答を読んだ後、サーバークラスとクライアントクラスを保持し、プラットフォーム固有のクラスを次のように置き換えることでモデルを単純化できることに気付きました#ifdefs(これは私が最初にやろうとしていたことです)。

このコードを使用する方が簡単ですか?少なくともファイルが少なくなることを意味します!欠点は、いたるところにFoobarあるため、クラスがやや「醜く」、少し読みづらくなることです。#ifdefsUnix Foobarのソースコードがコンパイラに渡されることはないため、これはと同じ効果があることに注意してください(呼び出すプラットフォーム固有のクラスを決定するために#ifdefも使用するため)。#ifdef

class Foobar {
public:
  int someData;

#if WINDOWS
  void someWinFunc1();
  void someWinFunc2();
#elif UNIX
  void someUnixFunc1();
  void someUnixFunc2();
#endif

  void crossPlatformFunc();
};

class FoobarClient : public Foobar;
class FoobarServer : public Foobar;

注:簡単な例として、いくつかのもの(ctorなど)は省略されています。

アップデート:

この問題の背景をもっと読みたい人のために、私は本当に適切なメーリングリストのスレッドをざっと読むことをお勧めします。3番目の投稿のあたりで物事が面白くなり始めます。また、関連するコードコミットがあり、ここで問題の実際のコードを確認できます。

4

5 に答える 5

10

できれば、メソッド内の操作のプラットフォーム依存の性質を含めて、クラス宣言がプラットフォーム間で同じままになるようにします。(つまり、実装で #ifdefs を使用します)

これができない場合、クラスは、プラットフォームごとに 1 つずつ、2 つの完全に別個のクラスにする必要があります。

于 2010-01-02T00:28:17.157 に答える
5

私の個人的な好みはifdef、メイク ファイルに魔法をかけることです。これにより、ソース コードは可能な限りクリーンな状態に保たれます。次に、プラットフォームごとに実装ファイルを用意します。もちろん、これは、サポートされているすべてのシステムに共通のインターフェースを考え出すことができることを意味します。

編集:

クロスプラットフォーム開発でこのような分母の低い設計を回避する一般的な方法の 1 つは、不透明なハンドルイディオムです。エスケープ ルートと同じ考え方ioctl(2)- プラットフォームごとに (できれば実装ファイルで) 個別に定義された不透明な前方宣言構造を返すメソッドを用意し、共通の抽象化が成り立たない場合にのみ使用します。

于 2010-01-02T00:35:44.433 に答える
2

コンパイルされた OS で他の OS の関数を使用しないことが十分にわかっている場合は、ifdef を使用すると多くの利点があります。

  1. 使用されていないコードと変数は実行可能ファイルにコンパイルされません (ただし、ここではスマート リンクが少し役立ちます)。
  2. どのコードがライブであるかを簡単に確認できます
  3. プラットフォームに依存するファイルを簡単に含めることができます。

ただし、OS に基づく分類には、次の利点があります。

  1. 1 つの変更を行うと、コードがすべてのプラットフォームでコンパイルされることを確認できます。
  2. コードとデザインがよりきれいになります

後者は、クラス本体自体でプラットフォーム固有のコードを ifdefing するか、コンパイル時にサポートされていない OS インスタンスを単に ifdefing することによって実現されます。

于 2010-01-02T00:26:49.317 に答える
2

私の好みは、プラットフォーム固有の問題を最下位のモジュールにプッシュし、それらを共通のインターフェイスにラップすることです。特定のメソッド、クラス、関数を個別の翻訳単位に入れます。リンカーとビルド プロセスで、結合する特定の翻訳単位を決定します。これにより、コードがよりクリーンになり、デバッグ時間がより簡単になります。

経験から、 を使用するプロジェクトがありました#ifdef VERSION2。1つのモジュールが使用されたため、デバッグに1週間かかりました#ifdef VERSION_2。バージョン 2 固有のコードがすべてバージョン 2 モジュール内にある場合は、より簡単に検出できる微妙な点です。

于 2010-01-02T00:43:26.980 に答える
0

プラットフォーム固有のコードに #ifdefs を設定するのは慣用的です。特に、あるプラットフォームのコードが別のプラットフォームで有効になっていると、コンパイルさえされないためです。私には良いアプローチのように聞こえます。

于 2010-01-02T00:26:48.147 に答える