C++头文件问题

来源:互联网 发布:linux主机 编辑:程序博客网 时间:2024/06/07 00:45

C++头文件问题

问题1:头文件中可以包含哪些东西

头文件中通常包含那些只能被定义一次的的实体,如类(class),结构体(struct),const, constexpr变量(C++11,用常量表达来赋值的常量),inline函数。如果头文件中只包含这些实体,即使头文件中不使用#pragma once或者#ifndef _TEST_, #define _TEST_, #endif。也不会出错,只不过是被包含的头文件可能会被包含多次,从而影响编译效率。但是不会出现重定义的错误。

问题2:#pragma once或者(#ifndef #define #endif)

如下代码:
#ifndef _TEST_#define _TEST_....#endif
或者是新的版本:
#pragma once
这种防止文件被多次包含的方法,只限于对单文件。可以避免同一个文件中有相同的不被允许的定义式,从而避免重定义的错误。例如:

//computer_system.h//#pragma once#ifndef _COMPUTER_SYSTEM_//#define _COMPUTER_SYSTEM_int test =0;//这并不是一个好主意,这里只是测试。#include "start.h"typedef unsigned char* byte_pointer;typedef unsigned int size_t;....#endif
//test.h#include"computer_system.h"
//test.cpp#include"computer_system.h"#include"test.h"int main(){return 0;}

将注释掉的#pragma once 和#define _COMPUTER_SYSTEM_还原就可以了。这个错误发生在编译阶段。

问题3:含有#pragma once或者#ifndef #define#endif等上述问题还会出现链接错误

对于单个文件下#pragma once可以保证int test = 0; 这样在头文件的定义式只被定义一次,但是在多个文件下,编译过后的各个实现文件的obj文件中都会定义一次test,这样在链接的时候,就会出现多次定义的错误。例如:

//imgprocess.h#pragma once#ifndef _IMGPROCESS_#define _IMGROCESS_...#endif

//imgprocessimpl.h#pragma once#ifndef _IMGPROCESSIMPL_#define _IMGPROCESSIMPL_...int test =0;...#endif

//imgprocess.cpp#include"imgprocess.h"#include"imgprocessimpl.h".....
//imgprocessimpl.cpp#include"imgprocessimpl.h"...

这样各个文件编译后得到的obj文件中都有一个test的定义,链接的时候就会发生重定义的错误。如下:

  

总结:

要写出正确的头文件,不仅要用#pragma once等条件编译符,还要在头文件中写出正确的内容,class,struct,inline函数,const,constexpr。需要注意的是,如果你想多个文件共享一个const对象,你需要在const前面加上extern关键字。并在其中一个地方给出定义式。