C++11类函数的多重定义
Posted
技术标签:
【中文标题】C++11类函数的多重定义【英文标题】:C++11 multiple definitions of class function 【发布时间】:2013-04-19 16:28:08 【问题描述】:已解决:我完全是个傻瓜。在仔细检查所有文件并通过我们专有的依赖文件生成器进行追溯后,事实证明确实存在最近添加到文件系统中的恶意 .cpp 包含,这导致了问题。对不起,谢谢大家的帮助!呵呵
我遇到了一个令人沮丧的难题,我希望有人能帮忙解决一个晦涩难懂的错误。基本上,我在头文件中声明一个通用类,如下所示:
//foo.h
#pragma once
class foo
public:
foo();
~foo();
void random_function();
;
请注意,我已经声明了一次 pragma 以防止多个定义,并且所有函数原型都放在类定义中。对应的类是这样定义的:
// foo.cpp
#include "foo.h"
foo::foo()
foo::~foo()
void foo::random_function()
//do stuff
这个类被用在很多其他文件中。例如:
// bar.h
#include “foo.h”
class bar
bar();
~bar();
std::shared_ptr<foo> get_foo();
std::shared_ptr<foo> my_foo;
;
但是当我编译时,对于类定义的每个函数成员,我都会收到以下错误:
bar.o: In function `foo:foo()':
dir/foo.cpp:80: multiple definition of `foo::foo()'
blah.o:dir/foo.cpp:80: first defined here
bar.o: In function `foo:foo()':
dir/foo.cpp:80: multiple definition of `foo::foo()'
blah.o:dir/foo.cpp:80: first defined here
注意连续两次重复相同的 3 行错误。对于每个构造函数/析构函数/函数声明,都会重复相同的错误模式。还要注意它似乎是在说 foo.cpp 中的函数 foo() 是首先在 foo.cpp 中定义的,这似乎没有多大意义。但我刚刚注意到,它以 bar.o 开头,然后是 blah.o...?
真的在这个问题上摸不着头脑,似乎无法破译问题出在哪里或我应该看哪里。任何帮助将不胜感激! :D
附录:
我无法发布原始代码,因为它来自我的工作。我希望这个示例 sn-p 至少足以为我应该从哪里开始寻找提供一些指导,除非当前设置的代码有任何问题。 我没有在代码的其他地方包含任何 .cpp 文件。我只包括 .h。 原始代码在头文件类声明的末尾有分号,只是忘记包含在此处发布的示例中。更新以反映这一点。 foo.h 的包含在所有文件中都是一致的(不会意外混合大小写)。 其他类似定义的类使用这个完全相同的模式,但奇怪的是没有产生相同的错误。 :? 重申一下,我确定我不会在程序的任何位置#include 任何 .cpp 文件,只有头文件会包含在程序的其他位置。 我也确定构造函数在头文件中声明为 foo();就像上面的代码示例一样,而不是 foo()。 编译器支持编译指示一次(使用 g++)。 修复了上述示例中在原始代码中找不到的另一个错字(头文件名周围的引号) 我正在处理的系统实际上非常大。整个代码中有许多包含和依赖项(甚至是一些循环依赖项),并且使用了一些在整个系统中传递的单例。上面的例子是我在最基本层面上看到的问题的简化表示,我看到的上述错误实际上是为我已经合并到系统中的许多新文件(不仅仅是一个)生成的.奇怪的是,我以类似方式定义的其他文件现在没有也没有产生这个问题,这就是为什么我很困惑它现在似乎导致了问题。【问题讨论】:
我认为课程必须以分号结束... 检查以确保您始终使用相同的大小写(例如,不包括foo.h
和Foo.H
。我似乎记得#pragma once
有一个错误,如果您包含该错误则不起作用具有不同大小写的文件。
代码看起来没问题。您是否尝试编译示例?它编译正确吗?因为如果确实如此,那么您的示例在此问题中无效。
我不想问这个显而易见的问题,但是您的编译器是否支持#pragma once
?所有#pragma
指令都是实现定义的。
听起来好像出于某种原因,文件bar.o
包含一些从文件foo.cpp
编译的机器代码。如果您确定所有包含都正确,请检查生成 bar.o
的 Makefile(或类似)命令,然后尝试删除并重建它。
【参考方案1】:
尝试在 foo.h 中添加
#ifndef FOO_H
#define FOO_H
//foo class and stuff
#endif
【讨论】:
我刚刚尝试了您的建议,但不幸的是没有任何变化。 @Blood:是的,我进行了更改并将所有编译指示一次调用转换为使用具有唯一名称的#ifndef/#define,如上例中在文件末尾使用#endif 和仍然没有变化。以上是关于C++11类函数的多重定义的主要内容,如果未能解决你的问题,请参考以下文章