2012-06-29 147 views
11

我想在C++中理解這一點。 如果類A有一個非虛方法,並且擴展A的類B覆蓋該方法,我可以創建B的一個實例並以某種方式使用B中定義的方法? 有沒有必要重寫一個非虛方法?我可以使用覆蓋非虛方法的方法嗎?

+1

你所描述的稱爲*隱藏*,而不是覆蓋。看看這裏,例如:http://stackoverflow.com/questions/2161462/c-inheritance-and-function-overriding – jrok

回答

31

是否有必要重寫一個非虛方法?

你實際上並沒有覆蓋,但是這是行爲,即

B* b = new B(); 
A* a = new B(); 
b->method(); //Calls B's method 
a->method(); // Calls A's method 

因此,指針/引用類型決定調用的方法。

我可以創建一個B的實例,並以某種方式使用B中定義的方法嗎?

是的。指針/引用類型必須是B類型的(參見前面的例子)。

如果不申報methodvirtual,你不能覆蓋它,但你可以隱藏它。

+0

很好的答案,謝謝 – Eyal

+1

一個「gotcha」是當'A'反過來是從一些基類(或實現一個接口)派生'virtual method()',在這種情況下'a->方法()'實際上會調用'B.method()'... – BadCash

+0

@Chip你錯過了強調差異。這個答案只有BadCashs評論完成。 – ManuelSchneid3r

9

如果從AB繼承,並重新定義了A定義的方法,那麼B新實例將調用B的版本。但是,如果該方法不是虛擬的,則不存在多態行爲,因此如果B的實例被引用爲A,則該方法將爲A。例如:

struct A { 
    void foo() { std::cout << "A::foo" << std::endl; } 
}; 

struct B : public A { 
    void foo() { std::cout << "B::foo" << std::endl; } 
}; 

B b; 
b.foo(); 
A *a = &b; 
a->foo(); 

的代碼的輸出以上將是:

B::foo 
A::foo 

然而,如果foo方法已經虛擬的,然後將B::foo已打印的兩倍。

+0

寫得很好! :) – niknak

2

如果函數不是virtual那麼變量的類型決定了執行被分派太:

#include <iostream> 

using namespace std; 

struct A { 
    void f() { cout << "A" << endl; } 
}; 

struct B : public A { 
    void f() { cout << "B" << endl; } 
}; 

int main(int args, char** argv) { 

    B b; 
    A& a = b; 

    b.f(); 
    a.f(); 

    return 0; 
} 
0
  • 沒有,沒有機制來覆蓋類A.
  • 非虛擬方法
  • 是的,則可以通過使用範圍解析運營商A使用從A類B中過載的非虛擬方法::方法名