2016-01-20 43 views
1

我遇到了一個我在網上找到的練習。 這個練習包含了我以前從未見過的「虛擬空白」。 所以鍛鍊含有1頭文件名爲plans.h如何調用虛函數void C++?

namespace plans { 

class HumanActions { 
public: 
    virtual void goTo() { } 
    virtual void haveANiceColdBeer() { } 
}; 

void applyPlan(HumanActions &actions); 

} 

和一個CPP文件

#include "Plans.h" 

using plans::HumanActions; 
using plans::applyPlan; 

void 
plans::applyPlan(HumanActions &actions) { 
    actions.goTo(); 
    actions.haveANiceColdBeer(); 
} 

我試圖通過讓運行像

#include "Plans.h" 

using plans::HumanActions; 
using plans::applyPlan; 

int main() { 
    HumanActions actions; 
    applyPlan(actions); 
} 
另一個主文件來運行功能

不幸的是,它不運行,它說我有'plans :: applyPlan(plans :: Actions &)'的未定義引用,所以我的問題是你如何通過這些論據的功能是什麼?

+0

虛擬函數應該在要使用的子類上實際創建,並且不能像那樣使用,所以您需要創建一個子類,填充函數然後使用它。 – Pooya

+0

它完全沒有返回 – MikeRi

+0

您是否已將兩個* .cpp文件鏈接到一個程序中? – aschepler

回答

1

你已經在頭文件中聲明瞭「void applyPlan(HumanActions & actions)」,但是你沒有在任何地方定義(實現)它,這就是爲什麼你有未定義的符號。

如果在main()中,您調用applyZombiePlan()而不是applyPlan(),您應該可以。

+0

糾正它仍然是相同的錯誤發生 – MikeRi

1

「未定義的引用」是一個鏈接器錯誤,這意味着無法找到函數的實現。換句話說,它通常意味着你聲明瞭這個函數,並且調用了這個函數,但實際上忘記了的寫入這個函數。

您的錯誤消息引用plans::applyPlan(plans::Actions&),但我看到的最接近的聲明是,它具有不同的參數類型。假設這不僅僅是你帖子中不同版本代碼的混淆,你可能會不小心聲明瞭兩個不同的函數,但只實現了其中的一個。

如果你的程序由多個.cpp文件,另一個可能的原因是,你不小心嘗試編譯和鏈接一個單一的文件,好像它是一個完整的程序,而不是所有的模塊連接在一起。這會使鏈接器看不到其他.cpp文件中定義的任何內容。如果您是初學者,最好的選擇是用一個命令行即時編譯所有源文件,例如g++ *.cpp -o myprog

調用虛擬函數與調用常規函數BTW沒有區別,反正它不是虛函數。

+0

謝謝! 我有2個cpp文件,並使用「g ++ main.cpp」運行它,並嘗試了您的方法,但sill給了我相同的確切問題。 它在main.cpp中說,所以我猜我沒有調用功能的權利。 – MikeRi

+0

我不認爲它的編譯器問題。我只是放棄它。謝謝你 – MikeRi

+1

嗯,這絕對是一個問題。它可能不是* only *的問題,但'g ++ main.cpp'將完全忽略'plans.cpp'的內容。 – Wyzard

0

我認爲你可以利用extern關鍵字。每當你實際定義你的全局函數時,你可以說void XYZ(){}和其他地方可以說extern void XYZ()。