【问题标题】:'Overriding' class member“覆盖”类成员
【发布时间】:2017-07-18 15:18:24
【问题描述】:

快速问题:我有一个带有成员变量的基类,我试图在派生类中“覆盖”这个值。我该怎么做?

我试过了:

class A
{
public:
    double i = 1;
};

class B : public A
{
public:
    double i = 2;
};


int main(int argc, char** argv)
{
    B* b = new B();
    A* a = b;
    std::cout << b->i << '\t' << a->i << std::endl;  // output 2    1
}

但所需的输出是“2 2”。 我做错了什么?

谢谢,

尼克拉斯

【问题讨论】:

  • 使用虚函数。
  • 你可以覆盖虚函数,而不是数据成员。
  • 为什么不在B的构造函数中给i赋值?

标签: c++ class polymorphism


【解决方案1】:

您可以覆盖虚拟函数;您不能覆盖数据成员。这个类层次结构有两个名为i不同成员,一个在A 类中,一个在B 类中。

如果您希望派生类更改基类中i 的值,只需在构造函数中进行:B() { i = 2; }。但更好的方法是为A 设置一个构造函数,设置i 的值,并从B 调用它:

A::A(int ii = 1) : i(ii) {}
B::B() : A(2) {}

【讨论】:

    【解决方案2】:

    还有一个比 Pete 提出的更简单的解决方案。

    只需像这样定义您的 B 类:

    class B : public A
    {
    public:
        B() { i = 2; }
    }
    

    这样 B 类将重用我在其基 (A) 中定义的成员,并且其默认值将“覆盖”为 2,因此您的测试代码将返回“2 2”。

    这就是你 1)不要更改基类 A(不要添加具有默认值的不必要的 int 参数,有些人甚至说具有默认值的函数参数在 c++ 中是一种不好的做法)和 2)不要在你的类中添加虚函数的开销(这在你的简单代码中也是不必要的)。

    【讨论】:

    • 如果我在 A 类中说 const double i,这似乎是不可能的。有没有办法解决它?
    • 不,const 是另外一回事,const 只能在构造函数(A)中初始化,所以在这种情况下你需要使用 Pete 的解决方案。
    猜你喜欢
    • 2020-03-11
    • 2014-01-02
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多