假設我有以下兩個文件,main.cpp
:編譯器如何知道要使用哪個catch塊?
#include <iostream>
class A {};
void foo();
int main(void)
{
try {
foo();
}
catch(const A& e) {
std::cout << "Caught an A." << std::endl;
}
return 0;
}
和foo.cpp
:
class A {};
class B : public A {};
void foo()
{
B b;
throw b;
}
現在,當我單獨編譯每個文件,鏈接生成的目標文件,並運行結果可執行文件,我得到預期的結果:
$ clang++ --std=c++14 -c main.cpp
$ clang++ --std=c++14 -c foo.cpp
$ clang++ --std=c++14 main.o foo.o
$ ./a.out
Caught an A.
而這讓我難以置信!類A
沒有虛擬方法。因此,它不是多形的,它的實例在運行時不應攜帶任何類型信息。 main.o
目標文件不知道正在拋出什麼,因爲實際拋出發生在foo()
內部,其主體在單獨的編譯單元中定義。目標文件具有更多信息,但同樣不瞭解任何捕獲語句和捕獲的異常的預期類型。
簡而言之:我沒有看到兩個源文件分別編譯然後鏈接如何生成上面的輸入,而無需處理一些運行時類型信息。這兩個文件分別編譯應該有足夠的信息來採取正確的catch塊。
B是A的子類,因此您可以在B的任何實例上查看A的「透鏡」。 – freestyle
爲什麼要重新定義「A類」? – Raindrop7
由於協變 – arturx64