1

私は抽象クラスAを持っています

class A{
 public:
  A(dim) : dim_(dim);
 private:
  int dim_;
}

そしてクラスB

class B : public A{
 public:
  B(int dim);
}

クラス B のコンストラクターを作成する必要があります。これは、dim > 1 の場合にのみ機能し、それ以外の場合はアサーションをスローします。

この場合

B::B(int dim) : A(dim){
  assert(dim > 1);
}

それは機能しますが、クラス A のインスタンスが作成されて削除されたため、良い解決策ではないと思います。

クラスAのinit-methodを作成するよりも:

class A{
 public:
  void init(int dim){
    dim_ = dim;
  }
  A(int dim){
    init(dim);
  }
 private:
  int dim_;
}

クラス B のコンストラクタを変更します。

class B : public A {
 public:
  B(int dim){
    assert(dim > 1);
    init(dim);
  }
}

しかし、うまくいきません。私の問題の解決策はありますか?

4

2 に答える 2

5

渡す値が常に より大きいことmyintを確認する小さなクラスを作成できると思います。int1

struct myint
{
    int data; 
    myint(int i) : data(i) { assert(data > 1); }
};

クラスで使用します。

class B : public A{
 public:
  B(myint dim) //this can still take int, due to implicit conversion! 
   : A(dim.data) { }
}

暗黙的に に変換され、変換が行われている間 (暗黙的に) assertをテストし、それが成功した場合にのみ、基本クラスに渡すことができるため、引き続きB渡すことを構築できることに注意してください。アサートが失敗した場合、プログラムは基本クラスのコンストラクターに入る前に中止されます (派生クラスでも何も初期化されません)。intmyintdim.dataA


次のように一般化することもできます。

//Summary : gint<N> makes sure that data > N
template<int N>
struct gint  //call it greater int
{
    int data; 
    gint(int i) : data(i) { assert(data > N); } //Use N here!
};

クラスで使用します。

class B : public A{
 public:
  B(gint<1> dim) //the template argument 1 makes sure that dim.data > 1
   : A(dim.data) { }
}

たとえば、別のクラスが必要な場合:

class Xyz : public A{
 public:
  B(gint<10> dim)  //gint<10> makes sure that dim.data > 10
   : A(dim.data) { }
}

かっこいいですね。

于 2013-01-05T20:45:39.997 に答える
0

2 番目のオプションを機能させたい場合は、空のコンストラクターを に追加する必要がありますAAただし、コンストラクター for に入る前にオブジェクトが作成されるため、これはあまり役に立ちませんB。したがって、空のコンストラクターがあるか、タイプ int のオブジェクトを取るコンストラクターがあるかに関係なく、常にタイプ のオブジェクトを構築しますA

A がこのサンプルで示されているように単純である場合、無効な薄暗い場合でもそれを構築することは大したことではないと思います。より複雑な場合は、 A の可能な限り小さな部分を初期化する A の ampty コンストラクターを作成してinitから、より複雑なことを行うメソッドを作成することをお勧めします。

于 2013-01-05T20:46:10.397 に答える