头文件引用多次的问题

YUKUILONGQQ 2010-07-06 04:29:09

//头文件 H1.H
#ifndef asdf
#define asdf
class a
{
public:
void f(int x,int y);
void g();
private:
int x,y;

};
#include<iostream>
void n()
{
std::cout<<"进入头文件"<<std::endl;
}
#endif



//文件gg.cpp 用于类a的实现
#include"H1.H"

#include<iostream>
void a::f(int a,int b)
{
x=a;y=b;
}
void a::g()
{
std::cout<<x<<' '<<y<<std::endl;
}



//主函数 kk.CPP
#include"H1.H"
int main()
{
a k;
k.f(1,4);
k.g();
n();
return 0;
}

编译时可过
连接时 出现错误
说 n()函数被重复定义
为什么 头文件中的
#ifndeif
#define asdf
。。。。。。
#endif
没有在用呢 ??
没有限定头文件的多次引入呢??

还有为什么编译可过 而连接是错呢
为什么呢 说说整个程序编译到连接的过程呀
...全文
583 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
jjyyka 2012-01-20
  • 打赏
  • 举报
回复
如果说头文件里有内联函数呢?
xingtianxixi 2010-08-06
  • 打赏
  • 举报
回复
感谢6、7楼。受教了呢……
loongee 2010-07-07
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 woshiyizhiyu04 的回复:]

gg.cpp和kk.cpp中都包含了该头文件,而你在头文件中定义了一个函数,这样子的话,头文件展开,在两个cpp中都包含了你定义的那个函数void n()。C++是单独编译的,每一个cpp文件会生成一个.obj文件,这两个.obj文件中都包含了void n()的二进制代码。在链接的时候,链接器会发现两个void n()的实现,从而造成链接错误。
结局的方法就如Erorr所说,在.h中声明该函数……
[/Quote]

楼上解答得很详尽了。至于说为什么不会出现类a的重复定义错误,是因为你的头文件里面拥有的是a类的声明,而不是实现。不信的话你把gg.cpp中类a的函数实现也搬到H1.h里面看看会不会报错。
delphiwcdj 2010-07-06
  • 打赏
  • 举报
回复
帮顶!
skyworth98 2010-07-06
  • 打赏
  • 举报
回复
sp,这个也是为什么头文件中一般不宜有具体实现的原因。

[Quote=引用 3 楼 ahao 的回复:]
把n()的定义放gg.cpp里去
[/Quote]
liyuxia713 2010-07-06
  • 打赏
  • 举报
回复
学习~

[Quote=引用 7 楼 woshiyizhiyu04 的回复:]
gg.cpp和kk.cpp中都包含了该头文件,而你在头文件中定义了一个函数,这样子的话,头文件展开,在两个cpp中都包含了你定义的那个函数void n()。C++是单独编译的,每一个cpp文件会生成一个.obj文件,这两个.obj文件中都包含了void n()的二进制代码。在链接的时候,链接器会发现两个void n()的实现,从而造成链接错误。
结局的方法就如Erorr所说,在.h中声明该函数,……
[/Quote]
YUKUILONGQQ 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 hai040 的回复:]
include就是简单复制

ifndef/define只是防止在同一个文件中多次引用同一个头文件
管不了在不同文件中的引用
[/Quote]
这样的话 怎么限定头文件中的重复定义呀
书上说 头文件中除了可以放声明的语句外
还可以放置 类的定义,const 对象 ,inline函数 那怎么限定它们的重复定义呀
YUKUILONGQQ 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 woshiyizhiyu04 的回复:]
gg.cpp和kk.cpp中都包含了该头文件,而你在头文件中定义了一个函数,这样子的话,头文件展开,在两个cpp中都包含了你定义的那个函数void n()。C++是单独编译的,每一个cpp文件会生成一个.obj文件,这两个.obj文件中都包含了void n()的二进制代码。在链接的时候,链接器会发现两个void n()的实现,从而造成链接错误。
结局的方法就如Erorr所说,在.h中声明该函数,……
[/Quote]
那为什么 class a 没有发现重复定义呢 ??
书上说
#ifndeif
#define asdf
。。。。。。
#endif
是头文件保护符,头文件保护符用于避免在已经见到头文件的情况下重新处理该头文件的内容
我在kk.CPP文件中已有一次H1.H的引用
然后执行main()函数
当遇到
k.f(1,4);
k.g();
时,又执行gg.CPP文件中的类a实现函数
但文件中还有一次H1.H头文件的引用
按书上说的,这次应该不引用
#ifndeif
#define asdf
。。。。。。//中间语句
#endif
中间的语句呀 所以不应出现重复定义的错误呀
那为什么 n()还重复定义呢
wahahatz1234 2010-07-06
  • 打赏
  • 举报
回复
顶7楼
maoloverme1 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 woshiyizhiyu04 的回复:]
gg.cpp和kk.cpp中都包含了该头文件,而你在头文件中定义了一个函数,这样子的话,头文件展开,在两个cpp中都包含了你定义的那个函数void n()。C++是单独编译的,每一个cpp文件会生成一个.obj文件,这两个.obj文件中都包含了void n()的二进制代码。在链接的时候,链接器会发现两个void n()的实现,从而造成链接错误。
结局的方法就如Erorr所说,在.h中声明该函数,……
[/Quote]
请问为什么没有提示class a重复?
autocfg 2010-07-06
  • 打赏
  • 举报
回复
用宏区分一下吧,.h文件最好别放实现
woshiyizhiyu04 2010-07-06
  • 打赏
  • 举报
回复
gg.cpp和kk.cpp中都包含了该头文件,而你在头文件中定义了一个函数,这样子的话,头文件展开,在两个cpp中都包含了你定义的那个函数void n()。C++是单独编译的,每一个cpp文件会生成一个.obj文件,这两个.obj文件中都包含了void n()的二进制代码。在链接的时候,链接器会发现两个void n()的实现,从而造成链接错误。
结局的方法就如Erorr所说,在.h中声明该函数,将函数的定义放在一个cpp中就可以了。
Erorr 2010-07-06
  • 打赏
  • 举报
回复
宏展开只在当前cpp文件有效,所以gg.cpp和kk.cpp里面都会展开并编译
只有在链接的时候才会发现重复定义了
解决的办法是把定义放到.cpp,.h里面声明一下
「已注销」 2010-07-06
  • 打赏
  • 举报
回复
在头文件第一行加上 #pragma once
hai040 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 pengxn 的回复:]
不是这样理解的吧。

没看出楼主的程序有什么问题
[/Quote]
就是在两个cpp里各有一个n
ahao 2010-07-06
  • 打赏
  • 举报
回复
把n()的定义放gg.cpp里去
pengxn 2010-07-06
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 hai040 的回复:]
include就是简单复制

ifndef/define只是防止在同一个文件中多次引用同一个头文件
管不了在不同文件中的引用
[/Quote]
不是这样理解的吧。

没看出楼主的程序有什么问题

hai040 2010-07-06
  • 打赏
  • 举报
回复
include就是简单复制

ifndef/define只是防止在同一个文件中多次引用同一个头文件
管不了在不同文件中的引用

64,654

社区成员

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

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