2012-04-19 7 views
2

少し低レベルなC++のものを書いていると、OS固有のものを書かなくてはならないことがよくあります。 MessageBox()関数を例にしましょう(フレームワークはこれを行うので素晴らしい例ではありませんが、それは簡単です)。クロスプラットフォームのC++ ...プラットフォーム固有のコードセクションを1つのファイルに格納するか、または別のクラスに格納しますか?

各プロジェクトがMyAppのようなカスタムサブクラスを提供するAppという基底クラスを持っているとします。それぞれのOSに複数のブロック#ifdefを持つ単一のApp::MessageBox()メソッドを持つことができます。代わりに、OSクラスのサブクラスが実装を提供する基本クラス/インタフェースを持つこともできます。例:AppWin32 : public App

一方の方法では後者が私にとってはやや似ているが、他方ではMyAppが正しいOS固有のサブクラスをサブクラス化するようにいくつかの醜いコードを使用しなければならないことを意味する。

もっと良い方法はありますか?

+2

*正しいOS固有の基底クラスをサブクラス化するためにいくつかの醜いコードを使用しなければならない* Uhm ... * ugly *コードは実際に名前を持っています:* Factory *デザインパターン。それは醜いと呼ぶだろう。 –

+0

OS固有の基本クラスのサブクラス化にファクトリパターンがどのように適用されますか? –

+0

@ John:工場は、入力条件(OSなど)に基づいて正しい特定の派生クラスを作成します。顧客は単にThingy :: Create(args)を呼び出し、Createはインスタンス化して戻す派生クラスを把握するためのすべての詳細を処理します。 – Bogatyr

答えて

0

実装をいくつかの.cppファイルに移動する場合は、1つの#ifdefブロックしか使用できません。しかし、必要がある場合は、これを2番目のaproachと組み合わせることもできます。それでも、単純な使用のために、私は複数の定義ファイルがそのトリックをやると思います。

2

ファイル/ソケット/メモリ/データベース/ ...関数は、GUI関数というよりもプラットホーム間での違いが少なく、ほとんどのコードはすべてのアーキテクチャで共有/コンパイルされます。私は#ifdefブロックを、これらの関数/クラス内のプラットフォーム固有のコードの周りに使用します。

完全に異なるGUI(または他の複雑なサブシステム)コードの場合は、プラットフォームディレクトリの下で別の実装(ヘッダー、多分内部ヘッダーではない)ファイルを使用する必要があります。 (ウィンドウ/ window.cpp、XWIN/window.cpp、MacOSXは/ window.cpp、...)

は、この方式では、wxWidgetsのかFLTKのためのGUIツールキットを見てみましょうか、他のほとんどの...

0

#ifdefは間違いなく最悪です。

プラットフォーム固有のコードをソースツリー(プラットフォームごとに1つのツリー)に分けることになります。プロジェクトの場所(特定のプラットフォームの場合)から、 "汎用"ツリー(例: "src")とプラットフォーム固有のツリー(実際にはLinux、Windows 、または他のプラットフォーム固有のソースルート)。 これにより、常に適切なバージョンのクラスを選択することが保証されます。さらに、異なるプラットフォーム用に設計された同様のクラスにも同じ名前を付けることさえできます。

もちろん、このアプローチはFATファイルシステムを使用しているWindowsでは不可能ですが、現在はまれです(WindowsではNTFSを使用しない理由がないため)。

1

IMOでは、いくつかのクラスはオープン/クローズなど単純すぎます。#ifdefはこのような状況では悪くありません。私は、単純な関数のための抽象的なプラットフォーム層を提供することは良い考えではない、それはオーバーエンジニアリングだとは思わない。

しかし、クロスプラットフォームは複雑です。ターゲットプラットフォームに存在しない特定のプラットフォーム機能を提供する場合は、抽象プラットフォーム層を作成し、プラットフォームごとに実装する必要があります。 Windowsのクリップボードは、X11のX Selectionsと大きく異なるため、異なるデータ構造とアルゴリズムを統一する必要があります。

関連する問題