【问题标题】:Child class calls parent member instead of its own member子类调用父成员而不是它自己的成员
【发布时间】:2018-01-03 17:14:54
【问题描述】:

我正在尝试通过两个类从一个公共父类继承某些成员来实现几个共享很多属性的类。实际上,改变的是它们处理特定成员的方式,这也将被继承,因为它需要从父类的其他成员那里获得:

#include <iostream>

class Parent{
public:
    Parent();
    Parent(const int _arg);
    ~Parent();
    int member1(const std::vector<float> _args);
    int member2(const std::vector<float> _args) { std::cout << shared(0.0) << std::endl;};
    int member3(const std::vector<float> _args);
    float shared(const float _val) {return 0.0;}; //dummy call in order for code to be compilable

protected:
    int protected_member1;
    int protected_member2;
    int protected_member3;
};

class Child1 : public Parent {
public:
    Child1(const int _arg):Parent(_arg);
    ~Child1();
    float shared(const float _val) {return 2.1;};
}

class Child2 : public Parent {
public:
    Child2(const int _arg):Parent(_arg);
    ~Child2();
    float shared(const float _val) {return 1.7;};
}

在实践中,shared(const float _val) 做了更复杂和特定问题的事情,我试图简化代码以便更清楚地说明问题(并删除了代码中不相关的部分作为其余类成员的定义)。但是,当我从每个子类调用 member2(const std::vector&lt;float&gt; _args) 时,调用的是基类成员 shared(const float _val) 而不是子成员。

int main(int argc, char const *argv[]){
    Parent p;
    Child1 c1;
    Child2 c2;

    c1.member2(std::vector<float> (5,1.0));
    c2.member2(std::vector<float> (5,1.0));

    return 0;
}

我做错了什么?解决问题的不同方法是否更有意义?

【问题讨论】:

  • shared 没有标记为virtual,那你为什么指望它参与虚拟调度呢?

标签: c++ class inheritance


【解决方案1】:

默认情况下,C++ 中不启用多态性(例如,与 Java 不同)。需要在基类中标记sharedvirtual

virtual float shared(const float _val) {return 0.0;}

如果您从不需要基类实现,那么您可以将其设为纯虚拟

virtual float shared(const float _val) = 0;

最后,在子类中,您也可以标记函数virtual,尽管这没有效果。从 C++11 开始,您可以在函数中使用 override 关键字,这可以提高程序的健壮性,因为从基类中撤消 virtual 会导致编译失败:

float shared(const float _val) override {return 2.1;}

【讨论】:

  • 如果你想要一个必须显式选择的实现,那么你可以使用纯虚拟实现......哦......我想我明白为什么有些人觉得 C++ 很难。
  • @UKMonkey:但它仍然是最好的通用语言。至少在我看来。
  • 一点也不反对 :)
  • @UKMonkey:大多数时候,你仍然只是遵循一套准则;仅仅因为你可以在 C++ 中实现一个纯虚函数并不意味着这样的事情经常发生在真实的代码中。如果您觉得有必要将实现添加到纯虚函数,那么您可能在继承和虚函数方面走得太远了,std::function 方法会更简洁。无论如何,来自 Java 或 C# 的人倾向于过度使用继承。
  • 很好的答案。但是,在单独的头文件和 cpp 文件中实现这一点的正确 sintax 是什么?只需将virtual 添加到基类成员,我就会遇到链接错误。
猜你喜欢
  • 2015-04-12
  • 1970-01-01
  • 1970-01-01
  • 2012-01-21
  • 1970-01-01
  • 2017-05-08
  • 2018-12-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多