在 C++ 中调用辅助类的重写方法
Posted
技术标签:
【中文标题】在 C++ 中调用辅助类的重写方法【英文标题】:Calling overridden method of helper class in 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
的实例。你需要了解对象切片
【参考方案1】:
-
复制构造函数不会复制派生对象,它会获取sliced 并创建一个基础对象。
更详细地说,您可以将复制构造函数视为“按值复制”,派生对象的每个值都将被复制以创建一个基础对象。由于您的 Helper 类没有类成员,因此它没有复制任何内容。
函数也是不可复制的,C++ 通过vtable 处理虚函数。基类会有一个基类的 vtable,这就是为什么 hb.something() 称为基版本。
-
最后一行是打印 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;
;
【讨论】:
【参考方案2】:class Base
中的 HelperBase hb
始终是 HelperBase
类型 - 即使您从 Child
类型的实例调用 print
。
有多种方法可以实现您想要的。一种选择是使用PIMPL 来存储指向Helper 类的指针。另一种选择是使用CRTP。
【讨论】:
以上是关于在 C++ 中调用辅助类的重写方法的主要内容,如果未能解决你的问题,请参考以下文章