麻烦大家帮我看看(关于全局变量的问题)
//head1.h
#ifndef HEAD1_H
#define HEAD1_H
#include <iostream>
using namespace std;
#endif
int h;
//head2.h
#ifndef HEAD2_H
#define HEAD2_H
#include "head1.h "
extern int h;
class a
{
public:
a();
~a();
private:
int b;
};
#endif
//c1.cpp
#include "head2.h "
//extern int h;
a::a()
{
h=0;
b=2;
for(int j=0;j <10;j++){
cout < < "h= " < <h < < ", i= " < <b < <endl;
}
}
a::~a()
{
}
//main.cpp
#include "head2.h "
extern int h;
int main()
{
h=1;
cout < < "h= " < <h < < "in main " < <endl;
return 0;
}
上面是我根据网上的指导写的测试全局变量的代码,但是编译时出现了错误,本想跟帖讨论的,但一看那些帖子都是几年前的,所以只好开帖了,麻烦大家帮忙看看,谢谢了:
/tmp/ccrbyH4S.o:(.bss+0x0): multiple definition of `h '
/tmp/ccooVVfU.o:(.bss+0x0):第一次在此定义
collect2: ld 返回 1
[解决办法]
2个.cpp文件都包括了#include "head2.h " , head2.h又#include "head1.h "
所以就会定义两次int h;
注释掉一个#inlude "head2.h "就可以拉
[解决办法]
把变量定义放进头文件中,那不是迟早要出重定义错误吗?
你如何能确保一个头文件只被一个cpp文件包括,而绝对不会再被第二个cpp包含?
[解决办法]
正确做法只在一个.c或.cpp文件中定义
int h; (比如在main.cpp)
而在头文件中,只是用
extern int h;
[解决办法]
"head2.h " 不需要include "head1.h ", 否则任何include了 "head2.h "的cpp文件都等于有下面两行:
int h;
extern int h;
当然是重复定义了。既然概念上head1.h 和 head2.h是假设要在不同的scope里面的(因为head2.h有extern int h,自然就是不认识head1.h了),那么后者包含前者逻辑上就没有意义了。
[解决办法]
楼主的问题在于不应该在头文件中定义一个变量,而是只能声明而已,要在另一个CPP中定义这个变量,这样就没问题了,我调试了楼主的程序,已经改好了,你可以拿去运行,没有错误:
//head1.h
#ifndef HEAD1_H
#define HEAD1_H
#include <iostream>
using namespace std;
extern int h; //这里改为extern,声明而已 ,把它放到endif里面
#endif
//head2.h //没有需要改的地方
#ifndef HEAD2_H
#define HEAD2_H
#include "head1.h "
extern int h;
class a
{
public:
a();
~a();
private:
int b;
};
#endif
//c1.cpp
#include "head2.h "
int h=100; //这里去掉extern声明,那么这个全局的h就是在这里唯一的定义了一次
a::a()
{
h=0;
b=2;
for(int j=0;j <10;j++){
cout < < "h= " < <h < < ", i= " < <b < <endl;
}
}
a::~a()
{
}
//main.cpp
#include "head2.h "
//把原来的那个声明去掉了,因为包含了头文件,没必要再声明
int main()
{
h=1;
cout < < "h= " < <h < < "in main " < <endl;
return 0;
}
[解决办法]
一个指导原则,尽量不要使用全局变量.
所有的全局变量都是可以用别的方法代替的(局部变量传引用.static变量传引用).
[解决办法]
全局变量重定义
别在.h里面定义变量
[解决办法]
//若为C++,把变量定义放在头文件中,如果此头文件包含超过一次都会有此问题。
//这样是否满足要求?
//head1.h
#ifndef HEAD1_H
#define HEAD1_H
#include <iostream>
using namespace std;
#endif
//head2.h
#ifndef HEAD2_H
#define HEAD2_H
#include "head1.h "
extern int h;
class a
{
public:
a();
~a();
private:
int b;
};
#endif
//c1.cpp
#include "head2.h "
int h;
a::a()
{
h=0;
b=2;
for(int j=0;j <10;j++){
cout < < "h= " < <h < < ", i= " < <b < <endl;
}
}
a::~a()
{
}
//main.cpp
#include "head2.h "
int main()
{
h=1;
cout < < "h= " < <h < < "in main " < <endl;
return 0;
}
[解决办法]
你可能会说,我调用f的上上上上层函数也要操作这个g那咋半.
不是还static变量么.根据你的逻辑可以定义在类中或函数中.
定义的函数中的static变量有个最大的好处就是,可以确定初始化顺序,而全局变量的初始化顺序是不确定的. 无论你多早需要这个变量,你会首先调用这个函数,返回的变量指针(或引用)都是给你初始化好的了.
[解决办法]
头文件中,
编码习惯是不定义,只声明!
只要有了声明,
那么这个具体的定义在工程中的哪个位置,
都是可以的 ~