C++ 覆盖基本成员值

C++ Override base member value

我有以下代码:

class A
{
public:
    int foo = 0;
};

class B: public A
{
public:
    int foo = 1;
};

int main()
{
    A *a = new B();

    std::cout << a->foo;
    std::getchar();

    return 0;
}

输出:0

为什么 B 不覆盖 A 的成员 foo ?

以及如何在不转换为派生的情况下获得所需的 1 输出 class

您只能重写 virtual 个成员函数。
所有其他成员,无论是函数、类型还是成员变量,都只能是 shadowed.

这意味着它们根本没有改变,但如果不引用正确的基础、使用范围解析运算符等就不容易访问。

所以,改为使用虚函数而不是成员变量。

使用虚函数。你不能有虚拟字段,因此你得到的值是你的实例指针的类型(A)而不是所指向的真实类型(B)。

#include <iostream>
using namespace std;

class A
{
    int foo_ = 0;
public:
    virtual int foo() const { return foo_; }
    virtual ~A(){}
};

class B: public A
{
    int foo_ = 1;
public:
    virtual int foo() const { return foo_; }
};

int main()
{
    A *a = new A();
    A *b = new B();

    cout << a->foo() << '\n';
    cout << b->foo() << '\n';
    cin.ignore();

    delete a;
    delete b;
}

B::foo 是一个完全独立于 A::foo 的成员。这就是为什么初始化 B::foo 不会更新 A::foo。您将不得不做更多类似的事情:

class
{
public:
    int foo;
    A(int value = 0) : foo(value) {} 
};

class B : public A
{
public:
    B() : A(1) {}
};

int main()
{
    A *a = new B();
    std::cout << a->foo;
    delete a;
    std::getchar();
    return 0;
}

如果您想使用多态行为,您可以为您的成员变量 "foo" 编写一个虚拟 getter 方法,因为不能直接多态访问数据成员。

您在下面修改了您的示例代码片段以实现该目的-

class A
{
    int foo;
public:
    A() { foo = 0; }
    virtual int getFoo() { return foo; }
};

class B: public A
{
   int foo;
public:
    B() { foo = 1; }
    virtual int getFoo() { return foo; }
};

int main()
{
    A *a = new B();

    std::cout << a->getFoo();
    std::getchar();

    return 0;
}