visual studio 2010 编译程序时,首先是cpp经过预处理,处理掉#define,#include等等。#include部分,将头文件部分替换到cpp中。之后进行优化过程,到.s。之后进入汇编,变成.obj。之后是将.obj链接在一起变为exe。
在这个过程中,比如 a.cpp,b.cpp都引入了c.h。
c.h中写下:
class Test{ }; enum xxx{ aaa =1, bbb =2, }; struct abc{ };
这些都是可以通过编译的。但是写下int x; 就无法通过编译,重复定义。
即使我们写成
#ifndef TEST_H #define TEST_H class Test{ }; enum xxx{ aaa =1, bbb =2, }; struct abc{ }; int x; #endif
还是会出现错误。
这是因为各自在由cpp生成到obj的过程中,引入头文件都是独立进行的。 ifndef的作用仅仅是一个cpp使用了很多次#include xxx.h 所带来的冲突。比如a.cpp引入了yyy.h,引入了xxx.h,同时xxx.h又引入了yyy.h,这样的话ifndef就会起作用。
当一个obj,链接到另外一个obj时,实际上include已经替换完毕。int x;会出现重复定义的问题。
而class就可以重复。即,每一个cpp都可以拥有一个类的一次定义,多次的话需要ifndef避免。
class A{};即是定义,又是声明。
class A;是声明。
在a.cpp中define
#define TEST #ifdef TEST #pragma message("TEST was defined! Found in a.cpp!") #endif
在b.cpp中define
#ifdef TEST #pragma message("TEST was defined! Found in b.cpp!") #endif
这样在编译后,
只输出"TEST was defined! Found in a.cpp!"
a中define的内容,b是看不到的。
编译是以cpp为单元进行编译的。各自独立的进行。
一个编译单元只能定义一次class,不能多次定义class。
不同编译单元各自定义一个class一次是可以的。