#ifndef PEOPLE_H #define PEOPLE_H #define _CRT_SECURE_NO_WARNINGS #include <string.h> #include <iostream> int a = 0; //这里只是多定义了一个变量. class people { private: char name[20]; int age; public: void set_name(char *s); void set_age(int i); const char * get_name(); const int get_age(); }; #endif 我知道在头文件定义变量是不规范的做法.我只是想了解.为什么即使在定义了宏的情况下.两个CPP文件包含该头文件依然会报变量a重复定义的错误. |
|
#ifndef PEOPLE_H
#define PEOPLE_H #endif 只是说明在在某一个编译单元不会重复包含,没有说在不同单元中不可以再次出现 |
|
5分 |
定义宏的目的:防止同一个cpp文件包含多次.h(有的时候同一个cpp会间接的包含多次同一个.h)
你的问题:在.h中声明变量,在多个.cpp中包含,编译时会在多个.o文件中有这个变量,所以在链接的时候会出错 |
5分 |
a是全局变量
B文件引用此头文件,不报错 C文件引用此头文件,不报错(没有重复定义) 此时,整个工程中 a变量因为是全局变量,就会被 定义两次,报错 |
15分 |
#ifndef PEOPLE_H
#define PEOPLE_H /* … */ #endif 这样写能够防止头文件被重复包含 在头文件中定义变量不是不规范,而是一种错误。 同样的, 在链接阶段,如果file1.o和file2.o链接在一起,变量a的定义就是重复的。 $ cat file1.c file2.c main.c header.h /* file1.c */ #include "header.h" /* file2.c */ #include "header.h" /* main.c */ #include <stdio.h> #include "header.h" int main(void) { printf("a=%d\n", a); return 0; } /* header.h */ #ifndef HEADER_H #define HEADER_H int a = 0; #endif $ nm file1.o file2.o main.o file1.o: file2.o: main.o: $ gcc -o demo file1.o file2.o main.o 正确的方法是,在header.h里声明变量,在一个单独的global.c文件里定义变量。 /* file1.c */ #include "header.h" /* file2.c */ #include "header.h" /* main.c */ #include <stdio.h> #include "header.h" int main(void) { printf("a=%d\n", a); return 0; } /* header.h */ #ifndef HEADER_H #define HEADER_H extern int a; #endif /* global.c */ int a = 0; $ gcc -c file1.c file2.c main.c global.c file1.o: file2.o: main.o: global.o: |
5分 |
a重复定义 一般这样用
#ifndef INIT #define DECLARE extern #else #define DECLARE // nothing!!! #endif DECLARE int a; 找一个cpp定义一个INIT, 包含头文件即可 |
5分 |
你要搞清楚编译错误 和连接错误
你每一个文件都是可以编译通过的,因为每一个文件里面都只有一个变量。 但是,在链接时,把各个文件链接成一个单独模块时,链接器发现各个文件都有同一个名字的变量,连接器没有办法把它们合并在一个模块里面。所以报错。 链接错误 和 编译错误是不一样的 |
用宏定义只解决编译时不会重复的问题,并无法解决链接时的问题
|
|
3分 |
定义成全局变量
使用的地方声明,就没这个问题 |
感谢耐心回复.如果一个CPP里定义了一个宏.可以作用在另一个CPP吗,当然是同一项目. |
|
2分 |
C/C++ 是以文件作为单独的编译单元的。
然后这些编译后的 .obj 文件有链接器链接成目标文件。 |