【问题标题】:Calling overridden method of helper class in C++在 C++ 中调用辅助类的重写方法
【发布时间】:2020-07-30 08:50:59
【问题描述】:

我来自 Python 背景,目前正在学习 C++ 中的 OOP。

我在弄清楚如何让代码调用继承到 HelperChild 的帮助器类 HelperBase 中的正确方法时遇到问题。

#include <iostream>

class HelperBase {
public:
    HelperBase() {}

    virtual void something() {
        std::cout << "HelperBase" << std::endl;
    }
};

class HelperChild : public HelperBase {
public:
    HelperChild() {}

    void something() {
        std::cout << "HelperChild" << std::endl;
    }
};

我在Base 类中使用的HelperBase 类,它被设置为成员变量。

class Base {
public:
    Base(HelperBase &helperBase) : hb(helperBase) {}

    virtual void print() {
        std::cout << "-- Base" << std::endl;
        hb.something();
    }
    HelperBase hb;
};

那么这个类作为类Child的基类:


class Child : public Base {
public:
    Child(HelperChild &helperChild) : Base(helperChild) {
        helperChild.something();
    }
};

main 方法是

int main() {
    HelperChild helperChild;

    Child child(helperChild);
    child.print();
    return 0;
}

这会输出以下内容:

HelperChild
-- Base
HelperBase

为什么最后一行没有打印“HelperChild”?为了实现这一点,我需要做哪些更改?(我不确定我是否以正确的方式使用了virtual)。

编辑: 在我试图弄清楚的实际情况中,Base::print 是一个非常大的方法,我不想在 Child 类中覆盖它。我只是想改变帮助类的行为。

【问题讨论】:

  • HelperBase hb;HelperBase,它不能包含HelperChild 的实例。你需要了解对象切片

标签: c++ oop polymorphism


【解决方案1】:
  1. 复制构造函数不会复制派生对象,它会获取sliced 并创建一个基础对象。

更详细地说,您可以将复制构造函数视为“按值复制”,派生对象的每个值都将被复制以创建一个基础对象。由于您的 Helper 类没有类成员,因此它没有复制任何内容。

函数也是不可复制的,C++ 通过vtable 处理虚函数。基类会有一个基类的 vtable,这就是为什么 hb.something() 称为基版本。

  1. 最后一行是打印 Helper base,因为您的 Base 有一个 HelperBase 但不是派生的 HelperChild

class Base {
public:
    Base(HelperBase &helperBase) : hb(helperBase) {}  // hp(helperBase) means you still have a helper base.

    virtual void print() {
        std::cout << "-- Base" << std::endl;
        hb.something();
    }
    HelperBase hb;
};

那么在mainchild.print()会调用属于HelperBase的hb.something()。

要实现多态,您需要一个指针来获取HelperChild 的实例。它被称为依赖注入,我假设您正在尝试实现它。

class Base {
public:
    Base(HelperBase &helperBase) {
        hb = &helperBase;
    }

    virtual void print() {
        std::cout << "-- Base" << std::endl;
        hb->something();
    }
    HelperBase* hb;
};

【讨论】:

    【解决方案2】:

    class Base 中的 HelperBase hb 始终是 HelperBase 类型 - 即使您从 Child 类型的实例调用 print。 有多种方法可以实现您想要的。一种选择是使用PIMPL 来存储指向Helper 类的指针。另一种选择是使用CRTP

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-05
      • 1970-01-01
      • 2014-10-04
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 1970-01-01
      相关资源
      最近更新 更多