Collected from here . . .
非虛成員函數的靜態解析。也就是說,成員函數是根據指向對象的指針(或引用)的類型靜態選擇的(在編譯時)。
相反,虛擬成員函數是動態解析的(在運行時)。也就是說,成員函數根據對象的類型動態選擇(運行時),而不是指向該對象的指針/引用的類型。這稱爲「動態綁定」。大多數編譯器使用以下技術的一些變體:如果對象具有一個或多個虛擬函數,編譯器會在對象中放置一個名爲「虛擬指針」或「v指針」的隱藏指針。 「這個v指針指向一個稱爲」虛擬表「或」v表「的全局表。
純虛函數是必須在派生類中重寫並且不需要定義的函數。使用curious = 0語法將虛函數聲明爲「純」。例如:
class Base {
public:
void f1(); // not virtual
virtual void f2(); // virtual, not pure
virtual void f3() = 0; // pure virtual
};
Base b; // error: pure virtual f3 not overridden
在此,鹼是一種抽象的類(因爲它有一個純虛函數),所以沒有類基地對象可以被直接創建:Base是(明確地)意味着是一個基類。例如:
class Derived : public Base {
// no f1: fine
// no f2: fine, we inherit Base::f2
void f3();
};
Derived d; // ok: Derived::f3 overrides Base::f3
實施例的虛擬或非虛擬Fenction
#include <iostream>
using namespace std;
class Base {
public:
virtual void NameOf(); // Virtual function.
void InvokingClass(); // Nonvirtual function.
};
// Implement the two functions.
void Base::NameOf() {
cout << "Base::NameOf\n";
}
void Base::InvokingClass() {
cout << "Invoked by Base\n";
}
class Derived : public Base {
public:
void NameOf(); // *Virtual function*.
void InvokingClass(); // *Nonvirtual function.*
};
// Implement the two functions.
void Derived::NameOf() {
cout << "Derived::NameOf\n";
}
void Derived::InvokingClass() {
cout << "Invoked by Derived\n";
}
主
int main() {
// Declare an object of type Derived.
Derived aDerived;
// Declare two pointers, one of type Derived * and the other
// of type Base *, and initialize them to point to aDerived.
Derived *pDerived = &aDerived;
Base *pBase = &aDerived;
// Call the functions.
pBase->NameOf(); // Call virtual function.
pBase->InvokingClass(); // Call nonvirtual function.
pDerived->NameOf(); // Call virtual function.
pDerived->InvokingClass(); // Call nonvirtual function.
}
如果我誤解你的問題的意圖,它是沿的線條更「編譯器如何解決其功能調用虛函數」,那麼[讀到這裏(https://stackoverflow.com/questions/ 3103153 /重載虛函數調用分辨率) – CoryKramer
你應該承擔[虛函數]看看[isocpp.org(https://isocpp.org/)常見問題解答(https://isocpp.org/維基/常見問題/虛擬函數#概述虛FNS) – NathanOliver
我已經寫代碼有意如此澄清疑點, 在1)編譯器會決定使用虛擬表,它必須調用的Foo :: foo的作爲指針是基類的 &in 2)編譯器靜態調用以調用Foo :: foo2。 那麼編譯器在閱讀語句後如何區分這兩種情況。 –