这是main.CPP:
#include "test.h"
//include "test.cpp"
int main(int argc, char *argv[])
{
return 0;
}
这是test.h:
//test.h就一句话
int i=999;
编译,没有问题。
如果我仅仅把.h后缀改为.cpp,然后用同样的方法,编译直接提示i重定义。
怎么回事?仅仅是文件后缀名改变了,其余都是一样的。
16 个解决方案
#1
h文件不包含是不会单独编译的,cpp文件会对应一个obj文件
#2
代码和文件后缀没关系的吧
至于i重定义,清理一遍再编译看看,就一个i也不可能有重定义啊
至于i重定义,清理一遍再编译看看,就一个i也不可能有重定义啊
#3
.h里面的定义都是内部链接的,是局部的。
.cpp里面的除非明确声明为局部的,则为全局的。
.cpp里面的除非明确声明为局部的,则为全局的。
#4
改成cpp 之后test.cpp单独编译一次 然后包含test.cpp又 编译一次
就发现了重定义
就发现了重定义
#5
现在.H文件是包含进去了的。
#6
包含进去也不会单独编译,而是和cpp文件一起存在于一个obj中,总之h文件不单独编译
#7
不对吧,现在我把main改为:
main.CPP:
#include "test.h"
int main(int argc, char *argv[])
{
printf("%d\n",i);
return 0;
}
按照你的说法,i是局部的,我在main.cpp里面根本没有extern过,那怎么可以照常使用呢?哈哈,你解释一下?
非const对象都是默认extern的,const对象才是默认内部作用域的。
#8
LZ。。。。
#9
铅哥,这好问题呢,从来没想过。。。。
#10
现在我把main改为:
main.CPP:
#include "test.h"
int main(int argc, char *argv[])
{
printf("%d\n",i);
return 0;
}
足以证明i是分配了空间的,要不然怎么可能使用呢?
.h不单独编译????你在.H里面乱打几个字符,看看编译是否通过????
另外,手工Makefile 一下就知道,仅仅用test.h,也是生成了test.obj的!
#11
改一下:
然后你再看看.h文件里面的定义会不会被提示重定义。
这是test.h:
//test.h就一句话
int i=999;
这是添加的test.cpp:
//test.cpp就一句话
#include "test.h"
这是main.CPP:
#include "test.h"
int main(int argc, char *argv[])
{
return 0;
}
然后你再看看.h文件里面的定义会不会被提示重定义。
#12
我从第一次学C++到现在,也有10年了,写了n多程序,也从来没有想过,因为我从来不在.H里面定义extern对象,只声明,今天偶然在.H里面定义了一个全部外部变量,然后到处包含这个文件,居然能通过,觉得奇怪。
#13
你把我那几句话放在VC里面编译一下?
#14
别用Makefile指定h,因为Makefile根本不管你的扩展名,标准的Makefile里面只有cpp和c文件(标准的gcc命令行和cl命令行不也不会明确指定h文件么?),不会有h文件,这就是我说h文件不编译的原因!
#15
首先:.h 是不会生成.obj文件的,那是因为LZ你之前改成.cpp生成的。
其次:你改成了.cpp,又#include "test.cpp",要知道编译器对每个.cpp文件都会生成一个.obj文件,
然后再把各个obj组合起来形成exe。这下你知道为什么会重复定义了吧。
然后:你在.h文件里定义int i = 0;那是因为include 时,把这个“包”进了obj,此时编译器当然为
它申请了空间了。
其次:你改成了.cpp,又#include "test.cpp",要知道编译器对每个.cpp文件都会生成一个.obj文件,
然后再把各个obj组合起来形成exe。这下你知道为什么会重复定义了吧。
然后:你在.h文件里定义int i = 0;那是因为include 时,把这个“包”进了obj,此时编译器当然为
它申请了空间了。
#16
你说对了,我犯了一个低级错误,没有清理上次的obj,
#1
h文件不包含是不会单独编译的,cpp文件会对应一个obj文件
#2
代码和文件后缀没关系的吧
至于i重定义,清理一遍再编译看看,就一个i也不可能有重定义啊
至于i重定义,清理一遍再编译看看,就一个i也不可能有重定义啊
#3
.h里面的定义都是内部链接的,是局部的。
.cpp里面的除非明确声明为局部的,则为全局的。
.cpp里面的除非明确声明为局部的,则为全局的。
#4
改成cpp 之后test.cpp单独编译一次 然后包含test.cpp又 编译一次
就发现了重定义
就发现了重定义
#5
现在.H文件是包含进去了的。
#6
包含进去也不会单独编译,而是和cpp文件一起存在于一个obj中,总之h文件不单独编译
#7
不对吧,现在我把main改为:
main.CPP:
#include "test.h"
int main(int argc, char *argv[])
{
printf("%d\n",i);
return 0;
}
按照你的说法,i是局部的,我在main.cpp里面根本没有extern过,那怎么可以照常使用呢?哈哈,你解释一下?
非const对象都是默认extern的,const对象才是默认内部作用域的。
#8
LZ。。。。
#9
铅哥,这好问题呢,从来没想过。。。。
#10
现在我把main改为:
main.CPP:
#include "test.h"
int main(int argc, char *argv[])
{
printf("%d\n",i);
return 0;
}
足以证明i是分配了空间的,要不然怎么可能使用呢?
.h不单独编译????你在.H里面乱打几个字符,看看编译是否通过????
另外,手工Makefile 一下就知道,仅仅用test.h,也是生成了test.obj的!
#11
改一下:
然后你再看看.h文件里面的定义会不会被提示重定义。
这是test.h:
//test.h就一句话
int i=999;
这是添加的test.cpp:
//test.cpp就一句话
#include "test.h"
这是main.CPP:
#include "test.h"
int main(int argc, char *argv[])
{
return 0;
}
然后你再看看.h文件里面的定义会不会被提示重定义。
#12
我从第一次学C++到现在,也有10年了,写了n多程序,也从来没有想过,因为我从来不在.H里面定义extern对象,只声明,今天偶然在.H里面定义了一个全部外部变量,然后到处包含这个文件,居然能通过,觉得奇怪。
#13
你把我那几句话放在VC里面编译一下?
#14
别用Makefile指定h,因为Makefile根本不管你的扩展名,标准的Makefile里面只有cpp和c文件(标准的gcc命令行和cl命令行不也不会明确指定h文件么?),不会有h文件,这就是我说h文件不编译的原因!
#15
首先:.h 是不会生成.obj文件的,那是因为LZ你之前改成.cpp生成的。
其次:你改成了.cpp,又#include "test.cpp",要知道编译器对每个.cpp文件都会生成一个.obj文件,
然后再把各个obj组合起来形成exe。这下你知道为什么会重复定义了吧。
然后:你在.h文件里定义int i = 0;那是因为include 时,把这个“包”进了obj,此时编译器当然为
它申请了空间了。
其次:你改成了.cpp,又#include "test.cpp",要知道编译器对每个.cpp文件都会生成一个.obj文件,
然后再把各个obj组合起来形成exe。这下你知道为什么会重复定义了吧。
然后:你在.h文件里定义int i = 0;那是因为include 时,把这个“包”进了obj,此时编译器当然为
它申请了空间了。
#16
你说对了,我犯了一个低级错误,没有清理上次的obj,