繁体   English   中英

在 C++ 中调用助手 class 的重写方法

[英]Calling overridden method of helper class in C++

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

我在弄清楚如何让代码在继承到HelperChild的助手 class 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;
    }
};

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

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

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

然后将此 class 用作 class Child的基础 class :


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 class 中覆盖它。 我只想改变助手 class 的行为。

  1. 复制构造函数不会复制派生的 object,它将被切片并创建基础 object。

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

此外 function 不可复制, C++ 通过vtable处理虚函数。 基础 class 将具有基础 class 的 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;
};

然后在main中, child.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;
};

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM