【问题标题】:Passing base class to function instead derived one将基类传递给函数而不是派生一个
【发布时间】:2020-08-13 10:16:52
【问题描述】:

我的继承有问题,这是我的示例代码:

#include <iostream>

struct Drawable {
    friend void draw( const Drawable &drawable );

    private:
        virtual void print() const = 0;
};

void draw( const Drawable &drawable ) {
    drawable.print();
}

class Rectangle : public Drawable {
    virtual void print() const override {
        std::cout << "Drawing rectangle...\n";
    }
};

class Square : public Rectangle {
    virtual void print() const override {
        draw( dynamic_cast< const Rectangle & >( *this ) );
        std::cout << "Drawing square...\n";
    }
};

int main() {
    Square square;
    draw( square );

    return 0;
}

更具体地说,使用此功能:

struct Square : public Rectangle {
    virtual void print() const override {
        draw( dynamic_cast< const Rectangle & >( *this ) );
        std::cout << "Drawing square...\n";
    }
};

有没有可能通过将这个类转换为 Rectangle 类型来调用 Square 类的绘图函数?

上面的例子和带有指针的例子会导致stackoverflow,因为Square类的打印函数无限运行。

感谢您的帮助!

【问题讨论】:

  • 是的,可以通过强制转换为 Rectangle 类来调用 Square 类对象的 Square 类的绘制函数。不,您不能在没有终止情况的情况下从 Square 类的绘图函数调用 Square 类的绘图函数,因为这会导致无限递归。
  • 您可以复制Square 的Rectangle 切片并将其作为临时传递给draw,如下所示:draw(Rectangle(*this));
  • 为什么要对派生类隐藏print()?让它protected。 example

标签: c++ inheritance polymorphism


【解决方案1】:

我不确定这是您的意图,但您可以显式调用 Rectangle 来自Square 的print() 的特定版本。

// draw( dynamic_cast< const Rectangle & >( *this ) );
Rectangle::print();
std::cout << "Drawing square...\n";

使用draw() 函数将始终选择更具体的 print() 的版本(由于 virtual)。


编辑,现在问题已经改变:你必须声明 print() 成员函数 protected 一直向下层级。

【讨论】:

  • 在打印函数是私有的情况下,有没有其他方法可以调用这个函数?
  • @Majrusz 如果它是私有的,那么必须将draw() 设为friend。您可能应该将其设为protected 以让派生类调用它。 example
  • @Majrusz 如果print() 成员函数是私有的,draw() 函数将无法调用它。
猜你喜欢
  • 2015-08-20
  • 1970-01-01
  • 1970-01-01
  • 2014-04-18
  • 1970-01-01
  • 1970-01-01
  • 2019-12-29
  • 2023-04-07
  • 1970-01-01
相关资源
最近更新 更多