0

抽象基本クラスとテンプレート化された派生クラスがあります。派生オブジェクトは、派生オブジェクトの前のインスタンスと、たとえば整数によって構築できます。これまでのところ

struct base {
  /* ...pure virtual functions here... */

  virtual ~base() = default;
  /* NO DATA */
};

template <class D>
struct derived : base {
  derived() = default;

  derived(int x, const derived& previous) {
    /* to construct I need access to previous.data_ */
  }

  /* ...overriden virtual functions here... */

  ~derived() = default;

  D data_;
};

派生クラスのコンストラクターは、派生オブジェクトのdata_メンバーにアクセスする必要があることに注意してください。ここで、整数と の以前のインスタンスを入力として取り、へのポインタを返すことによってprevious型のオブジェクトを構築する関数を作成したいと考えています。問題は、ユーザーがクラス ポインターを操作するため、関数が次のようになることです。derived<D>derived<D>basebase

template <class D>
std::shared_ptr<base> getNext(int x, std::shared_ptr<base> current) {
  return std::make_shared<derived<D>>(x, *current); /* ERROR */
}

baseご想像のとおり、これにより、 からへの既知の変換がないことを示すコンパイル エラーが発生しderived<D>ます。使用できることがわかっていることの 1 つstatic_cast<derived<D>&>(*current)は、基になるオブジェクトの型が常に であるためderived<D>です。ただし、理想的には、可能であればキャストを避けたいと考えています。この問題を克服する方法はありますか? 前もって感謝します!

4

3 に答える 3

1

派生クラスがどのタイプであるかを示す基本クラスで仮想アクセサー関数を使用できます。static castその後、安全に使用して基本クラスをキャストできます。

class Animal {
    virtual bool isDog() { return false; }
    virtual bool isCat() { return false; }
};

class Dog : public Animal {
    virtual bool isDog() { return true; }
};

class Cat : public Animal {
    virtual bool isCat() { return true; }
};

次に、次のように基本クラスを安全にキャストできます。

Dog A;
Cat B;

Animal *unknown_animal = &A;

if (unknown_animal->isDog()) {
    Dog *dog = static_cast<Dog*>(unknown_animal);
}
else if (unknown_animal->isCat()) {
    Cat *cat = static_cast<Cat*>(unknown_animal);
}

アクセサー関数は、派生型を知る必要があるだけでアクセスする必要がない場合にも役立ちます。

于 2013-10-18T14:45:35.417 に答える
0

static_castとにかく、これを使用したくないでしょう。使用したいと思いますdynamic_pointer_cast(結果をチェックして、派生型にキャスト可能であることを確認してください)。

オブジェクトに入力する必要があるすべての情報がインターフェイスにある場合はData、キャストを回避できる変換コンストラクターを作成できます。

template<typename T>
class MyDerived : public Base
{
public:
    // other functions
    MyDerived(std::shared_ptr<Base> p)
    {
        // initialize _data
    }

private:
    Data _data;
};
于 2013-10-18T14:40:41.090 に答える