11

私はマイクロプロセッサ(Arduino)プロジェクトに取り組んでいます。私のライブラリFooは既存のライブラリから継承されていますBasic。後で、 の機能をBasic別のクラスに拡張しましたAdvanced。ただし、Advancedハードウェアをさらに引き延ばすと、既に作成されたデモの 1 つが使用できなくなります。

私が考えているのは以下のようなものです。

class Foo:
#ifndef USE_BASIC
public Advanced
#else
public Basic
#endif
{
...
}

そして#define USE_BASIC私のデモコードを入れてください:

#define USE_BASIC
#include <Foo.h>

ただし、Foo は Basic から継承していません。ここで間違っていますか?または、この問題を解決するための代替手段がある場合は?

4

4 に答える 4

25

よりクリーンなソリューションは、 template を使用することです。テンプレート引数に応じて、コンパイラに基本クラスを選択させます。

以下に一例を示します。

 #include <type_traits> //for std::conditional


 //here you go with your own class
 template<bool UseAdvanced>
 class Foo : public std::conditional<UseAdvanced, Advanced, Basic>::type
 {
      //your code
 };

そして、このクラスを使用する方法は次のとおりです。

Foo<true>   fooWithAdvanced; //it uses Advanced as base class
Foo<false>  fooWithBasic;    //it uses Basic as base class!

それはそれを行う1つの方法です。しかし、もっと良い方法があります。具体的には、テンプレート引数が基本クラスとして機能する次の方法でクラス テンプレートを設計します。これにより、より柔軟な設計が可能になります。

 template<typename Base>
 class Foo : public Base
 {
      //your code
 };

したがって、必要な機能とその使用法をサポートしている限り、BasicAdvancedまたはその他のクラスを基本クラスとして使用できます。Foo

 Foo<Advanced>  fooWithAdvanced;
 Foo<Basic>     fooWithBasic;
 Foo<OtherBase> fooWithOtherBase;

それが役立つことを願っています。

于 2013-05-03T12:38:26.247 に答える
2

これは、ライブラリ ベンダーが常に直面している基本的な構成の問題です。小規模なプロジェクトの#define USE_BASIC場合は、必要に応じてfoo.hヘッダーに . 多くの構成オプションを持つ大規模なプロジェクトの場合は#include、すべてのライブラリ ヘッダーで d を取得する構成ファイルに移動し、そこで適切なものを定義することをお勧めします。その場合、構成ヘッダーですべての選択を行います。

// uncomment to use `Basic` throughout:
// #define USE_BASIC
#ifdef USE_BASIC
typedef Basic FooBase;
#else
typedef Advanced FooBase;
#endif
于 2013-05-03T12:35:15.260 に答える
1

パターン戦略を提案した人もいます。コンパイル時に選択する場合は、ポリシーベースの設計を使用することをお勧めします: http://en.wikipedia.org/wiki/Policy-based_design

これはあなたのものとほぼ同じデザインですが、テンプレートを使用します:

template <class Base> class YourClass : public base {
    ...
};

使用時:

#ifdef BASIC
typedef YourFinalClass Yourclass<Basic>;
#else
typedef YourFinalClass Yourclass<Advanced>;
#endif
于 2013-05-03T12:35:16.443 に答える