9

LinuxとWindowsでの実行をサポートするプロジェクトを維持する必要があります。このようなプリプロセッサディレクティブを使用する一部のコードは問題ありません。

#ifdef _WIN32 // _WIN32 is defined by Windows 32 compilers
#include <windows.h>
#else
#include <unistd.h>
#endif

しかし、いくつかは実際の実装であり、プリプロセッサディレクティブの使用を防ぎたいと思います。

void Foo()
{

    #ifdef _WIN32 // _WIN32 is defined by Windows 32 compilers
    code for windows 
    #else
    code for Linux
    #endif

    some common code...

    #ifdef _WIN32 // _WIN32 is defined by Windows 32 compilers
    code for windows again
    #else
    code for Linux again
    #endif

}

そのため、物事は複雑になり、維持するのが難しくなります。より良い方法はありますか?

4

5 に答える 5

9

従来の方法は、ラッパー関数で任意のOSに固有のすべてのコードを「非表示」にすることです。たとえば、特定のパスに基づいてすべてのディレクトリエントリを返す関数を使用して、より高いレベルの機能を実行する完全な関数でそれを行うことができます。入力として、または個々の基本機能を実装します。たとえば、、start_read_directory(path)-これread_dir_entry()end_read_directory()単なる例の機能であり、同じ原則をほとんどすべてのシステム固有の機能に適用できます。それを十分に包むと、あなたはあなたが何のためにプログラミングしているのかを知ることができなくなります。

本質的に、コード自体に多くの#ifdefがある場合、それは間違っています。

于 2013-01-29T21:11:02.300 に答える
8

コードではなく、ビルドシステムからOSの詳細を処理します。たとえば、Foo.cppには2つのバージョンがあります。1つはLinuxでコンパイルされ、もう1つはWindowsでコンパイルされます。理想的には、ヘッダーファイルは共通であり、すべての関数シグネチャは同一です。

于 2013-01-29T21:15:44.817 に答える
6

ファクトリパターンの簡略化されたバージョンを使用できます。

共通のインターフェースを持つ

class MyClass
{
public:
    virtual void Foo() = 0;
};

そして、プラットフォームごとに特定のクラスを作成します

#import <windows.h>
class MyClassWindows : MyClass
{
public:
    virtual void Foo() { /* Do something */ }
};

#import <linux.h>
class MyClassLinux : MyClass
{
public:
    virtual void Foo() { /* Do something */ }
};

次に、このクラスが必要な場合は、ファクトリを使用します。

class MyClassFactory
{
public:
    static MyClass* create()
    {
        #if defined _WIN32
            return new MyClassWindows();
        #elif defined _LINUX
            return new MyClassLinux();
        #endif
    }
}

このメソッドには、プラットフォーム固有の各クラスの.cppでMyClassFactory :: createメソッドを定義したり、適切なプラットフォーム用に.cppのみをコンパイルしたりするなど、さまざまなバリエーションがあります。これにより、すべての前処理ディレクティブが回避されます。切り替えは、正しい実装ファイルを選択することによって行われます。

于 2013-01-29T21:11:12.887 に答える
4

一般的なパターンは、システムに依存しないヘッダーファイルとプラットフォーム固有の実装ファイルを提供することです。

ヘッダーに固有のプラットフォームはありません:

class Foo
{
   ...
};

2つの異なる実装ファイルでは、foo_linux.cpp

 Foo::Foo() { .. linux code }

foo_windows.cpp

Foo::Foo() { .. windows code }

foo.cppでのプラットフォームに依存しない実装かもしれません

void Foo::plat_independent_function()

プラットフォームがビルドされ、foo.cppとfoo_platform.cppにリンクされます

于 2013-01-29T21:18:58.657 に答える
0

これを実装する可能性は、PIMPLイディオムを使用することです。この場合、クラスは「インターフェイス」を公開し、実装クラスへの無意味なポインターを宣言し(暗く、隠されたプライベートコーナーで)、ビルドシステムがプルを処理します。 PIMPLの実装を含むクラスの正しいプラットフォーム依存コードで。

于 2013-01-29T21:24:04.110 に答える