编译器链接程序的问题

wjb_yd 2010-04-19 04:43:57
A.h
void ff()
{
printf("ff");
}

a.cpp
include "A.h"
int main()
{
ff();
return 1;
}

b.cpp
include "A.h"
int main()
{
ff();
return 1;
}

如果一个工程中,这样使用了2个cpp,链接时会因为a.obj和b.obj中都有一个ff函数而链接报错。

但是如果我把代码改成这样,就不会报错。
A.h
class AAA
{
void ff()
{
printf("ff");
}
};

a.cpp
include "A.h"
int main()
{
AAA().ff();
return 1;
}

b.cpp
include "A.h"
int main()
{
AAA().ff();
return 1;
}
我不明白的时,我认为类的成员函数经过编译器处理之后,除了调用约定是this_call之外,其他应该没什么特殊的地方,那这样定义什么链接器就不会报错呢?
...全文
80 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
ForestDB 2010-04-20
  • 打赏
  • 举报
回复
这个跟C++没什么特别的关系。

// foo.h
void foo()
{
printf("foo");
}


// a.cpp
# include "foo.h"

void a()
{
}

预处理后变成

void foo()
{
printf("foo");
}

void a()
{
}


// b.cpp
# include "foo.h"

void b()
{
}

预处理后变成

void foo()
{
printf("foo");
}

void b()
{
}

然后进行编译,这里的foo是不是重复定义了?
先把这理解了再继续++吧。
wjb_yd 2010-04-20
  • 打赏
  • 举报
回复
谢谢9楼和12楼的朋友,我明白了。
oyjian 2010-04-19
  • 打赏
  • 举报
回复
1、需要添加public关键字
error C2248: “AAA::ff”: 无法访问 private 成员(在“AAA”类中声明)
2、没有类AAA的时候之所以出错是因为链接的时候发现有多个ff的版本,重定义了
3、使用AAA的时候之所以没有出错,是因为ff的声明和实现都在类内部,此时的ff实际是内联(inline)函数,inline函数的特点就是用到此函数的时候用代码替换,而不需要保护现场、恢复现场
4、如果在.h里面这样写就会出错:
class AAA
{
public:
void ff() ;
};
void AAA::ff()
{
printf("ff");
}
5、如果添加了一个inline关键字就不会有问题。
class AAA
{
public:
inline void ff() ;
};
void AAA::ff()
{
printf("ff");
}
6、关于inline,自己上网搜索吧
zcphoenix 2010-04-19
  • 打赏
  • 举报
回复
对于类的定义,编译器只保留一份吧。
zcphoenix 2010-04-19
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 wjb_yd 的回复:]

不好意思,我帖错了。
a.cpp只是一个空文件而已,除了include
a.cpp
# include "A.h"
[/Quote]
我说怎么看不懂呢!
这个应该是编译器单独编译源文件带来的问题,每个源文件(cpp)都是单独编译的,a.cpp => a.obj b.cpp =>b.obj,最后链接的时候,b.obj里面调用ff()函数的地方需要插入函数ff()的地址,但是a.obj和b.obj里面都有ff()函数,链接器就不知道用哪一个了。
tiantangniao232 2010-04-19
  • 打赏
  • 举报
回复
lz的这个问题其实还是重复定义的问题
在链接时编译器发现在多个目标文件里存在多份同样的定义就会出问题
lz的第一种把ff声明成static 或者在对应的A.cpp里定义就不会报链接错误
至于lz把ff封装到一个类里为什么没有问题,应该是因为内联函数的原因,编译期间的事
lz可以试试把A.h中ff的定义拿到外面来,如下:

class AAA
{
public:
void ff();
int a;
};

void AAA::ff()
{
printf("vvvvvvvvv");
}

像上面照样会报链接错误,但如果把ff变为inline---inline void ff()
就不会报链接错误
wjb_yd 2010-04-19
  • 打赏
  • 举报
回复
不好意思,我帖错了。
a.cpp只是一个空文件而已,除了include
a.cpp
# include "A.h"
zhangweiit 2010-04-19
  • 打赏
  • 举报
回复
就算是用函数,也编译不过去吧
因为,你有两个文件都有main啊
类和函数一样,重复定义都会编译不过去的
AlanBruce 2010-04-19
  • 打赏
  • 举报
回复
两个源文件中要么使用extern来声明类型和名称都相同数据对象

而且只能在一个地方定义
AlanBruce 2010-04-19
  • 打赏
  • 举报
回复
一个.h和一个.cpp组成一个编译单元

如果编译单元重复包含已定义对象。便会出现重复定义的局面了
wjb_yd 2010-04-19
  • 打赏
  • 举报
回复
3楼的朋友能讲的详细写吗?
如果成员函数是和对象绑定的,那声明对象很多的源代码编译出来的文件得多大啊~~~
pengzhixi 2010-04-19
  • 打赏
  • 举报
回复
成员函数是要和对象绑定的。
babyvox1999 2010-04-19
  • 打赏
  • 举报
回复
这样重复包含头文件就不会出错
babyvox1999 2010-04-19
  • 打赏
  • 举报
回复
包含头文件就是把头文件写入CPP中,你可以通过这样理解一下不能把函数和变量定义放在头文件的原因

64,676

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧