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 方法:

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课程,以确保int您通过的始终大于1

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) { }
}

请注意,您仍然可以构造Bpass int,因为它会隐式转换为myint,并且在转换发生时(隐式),它将测试assert,如果成功,只有这样您才能传递dim.data给 base class A。如果断言失败,您的程序将在进入基类构造函数之前中止(也不会在派生类中初始化任何内容)。


您甚至可以将其概括为:

//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

如果你想让你的第二个选项起作用,你必须添加一个空的构造函数到A. 然而,这对你没有太大帮助,因为A对象是在你进入构造函数之前创建的B,因此无论你有一个空构造函数还是一个接受 int 类型对象的构造函数,你总是会构造一个类型的对象A

如果 A 像您在此示例中显示的那样简单,我相信即使对于无效的暗淡,构建它也没什么大不了的。如果它更复杂,我建议你为 A 创建一个 ampty 构造函数,它尽可能少地初始化 A 的一部分,然后是一个init方法来做更复杂的事情。

于 2013-01-05T20:46:10.397 回答