从一个基类的指针对另一个基类的多重继承和泛型访问

Multiple inheritence and generic access to one base class from the other's pointer

本文关键字:基类 多重继承 另一个 泛型 访问 指针 一个      更新时间:2023-10-16

我的问题是:"如何实现处理不同子类但从两个基类访问方法的泛型函数?

请您想象我正在使用一个假设的图形库,其结构如下:

class Shape
{
// getters and setters are here
private:
   int m_BorderColor;
   int m_FillColor;
}
class Square : public Shape
{
}
class Triangle : public Shape
{
}
class TextBox : public Shape
{
}

。等等。

该库仅允许将 Shape 基类的派生添加到其假设画布中。在我的应用程序中,我希望每个形状都有一个文本框,可能还有一些其他属性。

因此,我想拥有自己的基类,如下所示:

class MyBase
{
public:
    SetText (string text) { m_Text.Text = text; }
    // other getters and setters here
private:
    TextBox m_Text;
    int m_Id;
}

然后,我可以将"我的"形状与文本框一起使用,如下所示:

class MySquare : public Square, public MyBase
{
}

我可以将MySquare添加到画布中,因为它是Shape的子类。当用户双击MySquare(或MyTriangle等)时我想更改文本。但我只知道在运行时点击了哪个形状。

以下内容显然不起作用,因为 SetText 不是 Shape 的成员,我从库中收到的指针,尽管(例如)指向 MyTriangle,但被转换为 Shape:

// double click handler
Shape* clicked_shape = clickEvent.GetShape();
clicked_shape->SetText("Foo");

我需要使用基类指针,因为直到运行时我才知道我得到的是哪个形状对象。因此,尽管以下内容工作正常,但对我来说没有用:

// double click handler
Shape* clicked_shape = clickEvent.GetShape()
((MyTriangle*)clicked_shape)->SetText("Foo")

感谢您对此问题的任何见解或更好的模式!

这个呢?

MyBase * base = dynamic_cast<MyBase *>(clicked_shape);
base->SetText("too");

您可能想要检查base是否为空,如果您获得的形状实际上不是您的形状之一。

为此,MyBase至少需要一个虚拟函数 - 析构函数就可以了。

Shape 类

是一个基类,因此它提供了一个可以重写的接口。 例如,可能draw()调用方法来绘制形状。这将是一个很好的候选者,可以在带有文本框的新类中被覆盖。例如:

class SquareWithText: public Square {
  void draw() {
    Square::draw(); // call base method
    ... // add text box here
}

这里没有多重继承,这为您提供了一个更简单的解决方案。如果单一继承不适合您,则可以选择更复杂的解决方案。

class ShapeWithTextBox : public Shape {
  void draw() {
     ... // add text box here
  }
}

现在,您将新类编写为:

class MySquare : public Square, public ShapeWithTextBox
{
  void draw() {
    Square::draw();
    ShapeWithTextBox::draw();
}

没有必要从Shape中得出ShapeWithTextBox。这取决于Shape class的接口。