2017-08-15 58 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; 
}