0

C++ 抽象クラスを作成しようとしていますが、このクラスの実装者に静的関数を含めるように要求する方法がわかりません。

例えば:

class AbstractCoolThingDoer
{
    void dosomethingcool() = 0; // now if you implement this class 
                                        // you better do this
}

class CoolThingDoerUsingAlgorithmA: public AbstractCoolthingDoer
{
    void dosomethingcool()
    {
        //do something cool using Algorithm A
    }
}

class CoolThingDoerUsingAlgorithmB: public AbstractCoolthingDoer
{
    void dosomethingcool()
    {
        //do the same thing using Algorithm B
    }
}

ここで、クールなことを行う方法の詳細を抜きにして、クールなことをしたいと思います。だから私は次のようなことをしたい

AbstractCoolThingDoer:dosomethingcool();

クールなことを行う方法を知る必要はありませんが、これには仮想と静的の両方の機能が必要であるように思われますが、これはもちろん矛盾しています。

理論的根拠は、CoolThingDoerUsingAlgorithmB が後で作成される可能性があり、できればクールなことを行う必要があるソフトウェアを書き直す必要がないことです。

編集:私が達成しようとしていることを明確にしているかどうかはわかりません. 私が満たそうとする3つの基準があります

  1. abstractcoolthingdoer を使用し、ライブラリが聞いたことのない別の coolthingdoer が作成された場合でも、これまで書き直す必要がないライブラリ。

  2. 必要な構造に準拠しない coolthingdoer を作成しようとすると、ライブラリを使用する実行可能ファイルはコンパイルされません。

  3. coolthingdoer には、必要な静的関数がいくつかあります。

おそらく悪いデザインを探しているので、より良いデザインを教えてください。工場は必要ですか?

4

2 に答える 2

2

たぶん、次のようなものが役に立ちます ( ideone.com の例を参照):

#include <iostream>

class A
{
 protected:
  virtual void do_thing_impl() = 0;
 public:
  virtual ~A(){}
  static void do_thing(A * _ptr){ _ptr->do_thing_impl(); }
};

class B : public A
{
 protected:
  void do_thing_impl(){ std::cout << "B impl" << std::endl; }
};

class C : public A
{
 protected:
  void do_thing_impl(){ std::cout << "C impl" << std::endl; }
};

int main() 
{
 B b_;
 C c_;

 A::do_thing(&b_);
 A::do_thing(&c_);  

 return (0);
}

編集: OP は実行時のポリモーフィズムを必要としないようですが、クラス インスタンスを必要としないコンパイル時のポリモーフィズム (static実装が派生クラスに隠されている場合の関数の使用、インスタンスは必要ありません)。以下のコードが解決に役立つことを願っています ( ideone.com の例):

#include <iostream>

template <typename Derived>
struct A
{
  static void do_thing() { Derived::do_thing(); }
};

struct B : public A<B>
{
  friend A<B>;
 protected:
  static void do_thing() { std::cout << "B impl" << std::endl; }
};

struct C : public A<C>
{
  friend A<C>;
 protected:
  static void do_thing() { std::cout << "C impl" << std::endl; }
};

int main() 
{
 A<B>::do_thing();
 A<C>::do_thing();

 return (0);
}

編集 #2: ユーザーが目的のパターンに従わない場合にコンパイル時に強制的に失敗させるには、ideone.com でわずかな変更を加えます。

#include <iostream>

template <typename Derived>
struct A
{
  static void do_thing() { Derived::do_thing_impl(); }
};

struct B : public A<B>
{
  friend A<B>;
 protected:
  static void do_thing_impl() { std::cout << "B impl" << std::endl; }
};

struct C : public A<C>
{
  friend A<C>;
 protected:
  static void do_thing_impl() { std::cout << "C impl" << std::endl; }
};

struct D : public A<D>
{
 friend A<D>;
};

int main() 
{
 A<B>::do_thing();
 A<C>::do_thing();
 A<D>::do_thing(); // This will not compile.

 return (0);
}
于 2013-09-09T22:32:27.523 に答える