2017-08-15 55 views
0

我已经以下代码:c + +覆盖基础构件值

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

为什么乙不会覆盖从A构件FOO?

,以及如何获得的1所需的输出而无需进行转换到派生类

+0

这不是压倒一切。它隐藏它。你不能有虚拟的领域,所以重写是不可能的。请参阅https://stackoverflow.com/questions/19290796/override-member-field-in-derived-classes。你可以使用一个函数。 –

回答

1

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; 
} 
3

您只能覆盖virtual成员函数。
所有其他成员,无论它们是函数,类型还是成员变量,只能是被遮蔽的

这意味着它们根本不会被改变,但是如果没有引用适当的基础,使用范围解析运算符或类似的方法就不容易访问。

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

2

使用虚拟功能。您不能拥有虚拟字段,因此您获得的值是针对实例指针的类型(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; 
} 
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; 
}