2016-01-20 44 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()。