【问题标题】:Altering virtual functions to add new parameters更改虚函数以添加新参数
【发布时间】:2020-07-27 12:34:38
【问题描述】:

我有一个基类A(它从未以其基形式实例化),它是许多子类的父类。 A 有一个每个子类都继承的函数,称为func。每个子类都有不同的func 实现,但每个子类的输入和输出是相同的。

在A中

virtual void func();

在每个子类中

void func();

在维护这段代码时,我意识到我实际上想向这个函数传递一个参数,就像这样

virtual void func(float foo);

然后,我显然天真地假设每个继承此函数的类都可以获取并使用此参数,但现在看来我必须遍历每个子类并将float foo 添加到它们的实现中func() 的定义,为每个添加 void func(float foo);。这种重复的改变难道不是 OOP 应该帮助避免的吗?我可以访问基类成员而无需复制它们的声明。我的问题是我是否滥用了 virtual 函数,有没有办法获得我想要的行为,或者这只是一个很难改变的事情?

【问题讨论】:

  • 如果你改变接口,你必须改变任何实现这个接口的类似乎很自然。
  • OOP 的另一个方面是重载,而不仅仅是覆盖。 func(TypeA &A) 与 func(TypeB &B) 不同,它们都与 func() 不同。
  • 继承应该防止定义被复制。覆盖的声明表示子类具有自定义行为(在其覆盖定义中)。您发现难以实现的内容实际上允许您的子类创建具有相同名称但与父类不同的签名的重载。如果要确保这一点,请使用 overridefinal 关键字。然后,如果签名发生变化,子类会收到警报,它们不再覆盖父方法,而是定义新的方法。
  • 不清楚是将void func() 更改为void func(float),还是添加另一个重载void func(float)。几个重载的问题是,除非使用适当的using,否则将隐藏未覆盖的重载。

标签: c++ inheritance design-patterns polymorphism


【解决方案1】:

我为这个问题想出的解决方案是创建一个数据结构,我通过引用将其传递给每个继承的函数。

// in parent
virtual void func(Data * _data);

// in child
void func(Data * _data);

public struct Data
{
    float foo;
}

这样,如果我想在函数中添加额外的输入,我可以简单地改变

public struct Data
{
    float foo;

    int bar; // only changed here!
}

并且不需要在整个程序中重复我的编辑(对性能的影响可能很小,需要额外的内存查找)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-28
    • 2012-10-15
    • 2016-11-26
    • 1970-01-01
    • 2018-08-05
    • 1970-01-01
    相关资源
    最近更新 更多