-2

整数とそのクラスの以前のインスタンスの 2 つの引数を取ることによって構築されるテンプレート クラスがあります。これらのクラスのインスタンスをコンテナーに格納できるようにしたいので、基本クラスから継承しています (非スマート ポインターは無視してください)。

class base {
  virtual base* getNext(unsigned x) = 0;
};

template <class D>
class derived :
  public base {

  /* no memory allocation here, simply changes the data in next */
  void construct_impl(unsigned x, const derived<D>& previous, derived<D>& next); 


  derived();            /* default constructor */

  derived(unsigned x, const derived<D>& previous) { /* construct from previous object */
    allocate_memory_for_this();
    construct_impl(x, previous, *this);
  }

  base* getNext(unsigned x) {
    return new derived(x, *this);
  }
};

ここで、同じ方法でbaseオブジェクトを構築するクラスに関数を作成したいと思います。つまり、メモリを新たに割り当てません。こんなことを考えていたderived<D>construct_impl

class base {
  virtual base* getNext(unsigned x) = 0;
  virtual void  getNext_noalloc(unsigned x, base* already_allocated_derived_object) = 0;
}

このような派生クラスでオーバーライドされます

void getNext_noalloc(unsigned x, base* already_allocated_derived_object) {
     construct_impl(x, *this, *already_allocated_derived_object);    
}

base*からへの変換がないため、残念ながらコンパイルされませんderived<D>*(static_castを使用しない限り)。必要なものを達成する方法はありますか? 前もって感謝します!

4

2 に答える 2

2

C++ で次のように記述できるという誤解に苦しんでいる可能性があります。

class ClownCar {
    unsigned int x;
    ClownCar inner_car;
};

しかし、これは不可能です!何でしょsizeof(ClownCar)う?少なくともsizeof x + sizeof inner_car;である必要があります。すなわち、sizeof(unsigned int) + sizeof(ClownCar); つまり、それ自体よりも少なくとも 4 バイト大きくなります。

そのため、クラスに独自のクラスのインスタンスを含めることはできません。仮想であろうとなかろうと、継承はここでは関係ありません。どうしようか?ポインターを使用します。

class ClownCar {
    unsigned int x;
    ClownCar *inner_car;
public:
    ClownCar() : x(0), inner_car(nullptr) {}
    ClownCar(unsigned int x, ClownCar *previous) : x(x), inner_car(previous) {}

    ClownCar *getNext(unsigned int x) {
        return new ClownCar(x, this);
    }
};

int main() {
    ClownCar inmost_car;
    ClownCar *car1 = inmost_car.getNext(42);
    ClownCar *car2 = car1.getNext(43);
    // ...
    delete car2;
    delete car1;
    // of course we don't delete inmost_car, since it lives on the stack
}

もちろん、これはあまり C++ 風ではありません。おそらく、これらすべての を取り除き、*各車がその内側の車の「所有権を取得」するようにします (また、それを削除する責任も負います)。標準ライブラリを使用して、std::unique_ptrこの「所有権」の概念を表すことができます (コンストラクターまたは関数に unique_ptr 引数を渡すにはどうすればよいですか?も参照してください)。のリンクされたリストでありClownCar、これは STL が無料で提供してくれるものです。

struct ClownCar { unsigned int x; };
typedef std::list<ClownCar> ClownCarList;  // ta-da!

ですから、本当の問題は、何を達成しようとしているのかということだと思います。

于 2013-10-25T01:00:12.080 に答える