将基类初始化为派生基类?

时间:2011-01-14 05:03:47

标签: c++ oop

我认为这不可能,但如果是的话,我觉得这很有用。

我正在制作一个用户执行paint事件的Gui API。让我们说我想制作一个数字文本框。好吧,从TextBox继承它似乎是一种好习惯。这个问题是,用户因为

而无法重新实现文本框的绘制事件
TextBox::paint();  

只会调用我的默认绘制方式。

如果他们必须保留所有TextBox衍生物,那将会很烦人。

有没有办法解决这个问题?

让我说我的TextBox描绘一个正方形,然后数字部分添加一个圆圈,但用户的文本框,从我的TextBox派生一个三角形,我的数字从我的TextBox派生我希望结果是三角形,圆形

由于

3 个答案:

答案 0 :(得分:1)

正如我在评论中所说,我认为桥接模式实际上是你想要的,但是因为你试图将用户的类作为NumericField事物的基类插入,所以你要做的就是:

template < typename Base = TextField >
struct NumericField : Base
{
 ...
  void paint() { Base::paint(); draw_circle(); }
};

现在用户可以使用NumericField<>或者他们可以插入他们的类:

struct UserField : TextField
{
  ...
  void paint() { draw_triangle(); }
};
NumericField<UserField> my_field;

桥梁答案看起来更像是:

struct TextField
{
  TextField() : extender_(new null_extender) {}
  ...
  void set_extender(extender*);
  virtual void paint() { draw_square(); extender_->paint(); }
  ...
};

struct extender { virtual void paint() = 0; };
struct null_extender { void paint() {}};
struct numeric_extender { void paint() { draw_circle(); }};

struct UserField
{
  void paint() { draw_triangle(); extender()->paint(); }
};

很多细节都没有,但那就是故事。

答案 1 :(得分:0)

NumericTextBox和TextBox之间的唯一区别是前者只允许输入某些字符吗?你想要它以不同的方式绘画吗?

答案 2 :(得分:0)

我不太确定你的意思。你的问题不是那么清楚。

标题似乎在问如何调用基类初始化器或构造函数, 这就是你想要的吗?

如果这是你想要的,那就像这样。

class TextBox
{
  public:
  TextBox() { }
  virtual ~TextBox() { }

  virtual Paint() { }
};

class NumericTextBox : public TextBox
{
  public:
  NumericTextBox() : TextBox() { }
  ~NumericTextBox() { }

};

确保TextBox :: Paint的基类和任何其他方法都被声明为虚拟和析构函数。