2014-04-01 62 views
0

我的目的是查找調用某個函數的所有地方。 因此,我從中定義了新的類,並使其不可訪問。 但我沒有定義該方法,並且出現鏈接錯誤。在Class中聲明但未定義的虛方法

下面是代碼:

A.hpp

#ifndef _A_HPP 
#define _A_HPP 
class _declspec(dllexport) A 
{ 
public: 
    virtual void f1(); 
}; 
class _declspec(dllexport) B: public A 
{ 
private: 
    void f1(); 
}; 
#endif 

A.cpp

#include "A.hpp" 
void A::f1(){} 

program.cpp

#include "A.hpp" 

int main(void) 
{ 
    A a; 
    a.f1(); 
    return 0; 
} 

B::f1()永遠不會被調用,但我仍然有鏈接錯誤。 但是,如果您刪除_declspec(dllexport)它生成OK。

+0

和錯誤說??? – Abhineet

+0

(1)你不能使一個可訪問的函數不可訪問(2)一個全新的類對程序的其餘部分的編譯沒有影響(3)所有的虛擬函數都必須被定義,無論它們是否被調用。 –

+0

你已經失蹤了;課後 – Renjith

回答

1

的功能是由一個虛函數表類A.

http://en.wikipedia.org/wiki/Virtual_method_table

你不能有虛函數(除了純虛函數)是未定義的引用。必須定義它們以便定義虛擬表。

使功能變爲私有也是徒勞的,因爲只需調用(& A).f1()將調用B :: f1()。


編輯澄清關於你的編輯,編譯以下與沒有優化,

struct Foo { virtual void foo(); }; 
struct Goo : public Foo { void foo() {} }; 

int main() 
{ 
     Goo f; 
     return 0; 
} 

導致鏈接錯誤(使用GCC),

​​

這是符合市場預期。在你的情況下,刪除導出會發生什麼,MSVC可能會作弊。它看到整個班級及其所有用途,並且不會生成虛擬表格。它優化了它。它知道你並沒有在外部代碼中使用這個虛擬表,所以它不會理睬它。

如果我爲了完全相同的原因打開優化編譯,我也沒有錯誤。

+0

對不起,我想你誤解我的代碼,Goo從未被使用過。 – user2746019

+0

這與Foo或Goo無關。 – user3427419

相關問題