2016-03-03 80 views
2

我一直在努力去理解,爲什麼我可以在頭文件中創建一個純虛函數,這個頭文件還沒有在我正在使用的庫中實現,而且這不會導致鏈接或甚至運行時失敗.. 上面可能有點不準確,但這裏有一些代碼來備份它。C++共享庫:純虛函數不會導致鏈接錯誤

下面是一個接口定義:

class A 
{ 
public: 
    static A* Create(); 

    virtual ~A() {} 

    virtual status_t start() = 0; 
    virtual status_t stop() = 0; 
}; 

我有一個C++共享庫,它包含的實現 「的AIMP1」 +的A ::創建()函數(見下文):

A* A::Create {return new AImpl;} 

class AImpl : public A 
{ 
public: 
    A() {} 
    virtual ~A() {} 

    virtual status_t start() {} 
    virtual status_t stop() {} 
}; 

我建立共享庫 - 沒問題。 現在我在頭文件中添加另一個純虛函數爲A類:

class A 
    { 
    public: 
     static A* Create(); 

     virtual ~A() {} 

     virtual status_t start() = 0; 
     virtual status_t stop() = 0; 
     virtual status_t write() = 0; 
    }; 

創建一個使用它的測試程序:

void main() 
{ 
    A* a = A::Create(); 
    a->start(); 
    a->stop(); 
    a->write(); 
} 

現在我明白的是,上述編譯,但我認爲它會失敗鏈接,因爲共享庫中沒有write()調用的實現。 即使在運行時,也不會發生崩潰或發生任何事情。它看起來像寫呼叫被跳過。任何人都可以幫助解釋 - 這將不勝感激:-)

謝謝 - 而對於冗長的問題,對不起,這是一個有點難受,解釋了「單排」確切的問題..

+1

您確定在更改代碼後重新編譯了它嗎?你能強制重建嗎? – leemes

+0

是的,我相信它是重新編譯的。但正如我看到編譯器不應該抱怨。代碼沒問題。但是在lib中缺少實現,所以我會猜測鏈接錯誤。 –

+0

你還重新編譯了這個庫嗎?由於'AImpl'是抽象的,我猜這個編譯應該在'A :: create'中失敗。 – leemes

回答

0

發生什麼事情是共享庫是用A類的一個版本構建的,而可執行二進制文件是使用不同版本構建的。此時,您違反了一個定義規則,編譯器可以自由地執行任何操作,包括成功編譯和鏈接您的代碼。在這種情況下,不需要編譯器診斷。

+0

謝謝 - 是的,這似乎是一般性結論。編譯器/鏈接器不會幫助我在與純虛函數鏈接舊庫時的情況。令我感到驚訝的是 - 但我將不得不處理這些問題:-) –

0

純虛函數不會在鏈接過程中導致任何錯誤。相反,如果嘗試對抽象類型的對象進行檢驗,純虛函數將導致編譯錯誤。

Reminer - 抽象類型是一種(直接或間接通過繼承)至少有一個未被覆蓋的純虛函數。

+0

感謝您的快速回答 - 您的意思是說,當我與使用舊版本A的庫鏈接時,上述內容不會導致任何錯誤? –

0

如果解決方案之前已經構建,則可以編譯或構建。這意味着它使用舊的目標代碼。嘗試做一個乾淨的解決方案,然後重建它。一旦你的解決方案被清除。然後嘗試編譯繼承的類。另一件值得關注的事情是,您已將您的繼承類聲明爲:

class AImpl:A {...};

我的問題就是如何從A繼承AImpl?你打算publicprotectedprivate繼承?

編輯

如果您鏈接到這是一個圖書館和當前的解決方案並沒有表現出任何的編譯,安裝,連接錯誤;這是因爲您當前的解決方案正在使用已經構建的舊libdll。如果你回到你的庫解決方案並做一個乾淨的構建,它不應該編譯,因此你不會有一個更新的版本庫鏈接到。

+0

謝謝。你是對的,真正的代碼具有公共繼承。我將更新帖子以表明這一點。我知道重新編譯共享庫(具有實現)將導致編譯錯誤。但我很驚訝我可以在頭文件中添加新的純虛方法,而不會在使用共享庫的應用程序中發生任何編譯/鏈接錯誤。即使在運行時,我也沒有得到任何錯誤 - 只是跳過電話似乎? –

+0

@ user6014883我編輯了我的答案,添加了一個新的部分,解釋了鏈接庫時會發生什麼情況。 –

+0

是的,謝謝你的評論。我從意見中瞭解到,確實我不應該指望舊圖書館有任何編譯/鏈接錯誤。這對我來說有點令人驚訝 - 但我只需要處理:-) –