将基类传递给函数而不是派生一个

Posted

技术标签:

【中文标题】将基类传递给函数而不是派生一个【英文标题】: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 类的绘图函数?

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

感谢您的帮助!

【问题讨论】:

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

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

// 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() 函数将无法调用它。

以上是关于将基类传递给函数而不是派生一个的主要内容,如果未能解决你的问题,请参考以下文章

虚函数总结

将基类的对象传递给派生类的引用函数

为啥当我有两个函数时编译器没有显示错误,一个将基类作为参数,一个将派生类作为参数?

将基类转换为派生类[重复]

使用shared_ptr将基类引用值复制到映射

与简单地创建派生类指针相比,将基类绑定到派生类有啥好处?