请教一个头文件重复包含的问题?

时间:2021-01-18 16:49:16
我有一个类CPos。在CPos中有如下定义:


Pos.h
--------------------------------------------------------
#if !defined(AFX_POS_H__22F9CC51_D3E6_4A6D_AAEB_DFD8F78402FB__INCLUDED_)
#define AFX_POS_H__22F9CC51_D3E6_4A6D_AAEB_DFD8F78402FB__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

char CMD_RESET[] = { STX, 0x5F, ETX, 0x5C };            // 打印机重置
char CMD_DISCHARGE_RESUSE[]   = { STX, 0x50, '0', ETX, 0x63 };    // 弹出卡到空闲位置 [ 可再次读入 ]

class CPos...
{
...
}
...

我在TestDlg.h中包含

#include "pos.h"


并在TestDlg.cpp中调用:

m_pos.write( CMD_RESET, strlen(CMD_RESET), (LPDWORD)&writelen );


错误:Linking...
StdAfx.obj : error LNK2005: "char * CMD_RESET" (?CMD_RESET@@3PADA) already defined in CommDlg.obj


Pos.h中不是已经包含了#pragma once吗?为什么还会产生重复定义的错误呢?

该如何解决呢?谢谢!

9 个解决方案

#1


如果_MSC_VER<=1000呢

#2


CMD_RESET换个名字呢

#3


估计是与预定义的同名了。建议换一个名字试试

#4


char CMD_RESET[] = { STX, 0x5F, ETX, 0x5C };            // 打印机重置

不是头文件重复包含,而是你的工程里面应该还有一个CommDlg.h 或者cpp。
pos.h里面的这个定义CMD_RESET,和commDlg的重复了。

#5


情况是这样的:
我用的是MFC的对话框,我在工程中新建了一个新类CPos。




Pos.h
------------------------------------------------


#if !defined(AFX_POS_H__22F9CC51_D3E6_4A6D_AAEB_DFD8F78402FB__INCLUDED_)
#define AFX_POS_H__22F9CC51_D3E6_4A6D_AAEB_DFD8F78402FB__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <string>
using namespace std;

Command CMD_PRINTER_RESET        = { 0x5F, 6,  3000 };

...

#endif // !defined(AFX_POS_H__22F9CC51_D3E6_4A6D_AAEB_DFD8F78402FB__INCLUDED_)


Pos.cpp
-------------------------------------------

#include "stdafx.h"
#include "Comm.h"
#include "Pos.h"
#include "pcbdll.h"
#include <fstream>
using namespace std;


StdAfx.h
-------------------------------------------------
...
#include "pos.h"





其它对话框等cpp文件就没有包含pos.h文件了,都是向导生成的默认包含头文件,主要是包含stdafx.h。

请问我的问题出在哪呢?

谢谢!!

#6


头文件里只放声明,不要放定义(类定义除外)

#7


不要把全局变量的实现放在头文件里,头文件里应该放申明:

extern Command CMD_PRINTER_RESET;[code]

在某个cpp文件里再定义

[code=C/C++]Command CMD_PRINTER_RESET        = { 0x5F, 6,  3000 };


楼主理解错了#pragma once的意思, 
pragma once可以避免在一个cpp文件里引用俩次相同的头文件导致的重复定义。但是在不同的cpp里,两处引用都会起作用,所以就生成了两个全局的同名变量 CMD_PRINTER_RESET,编译器就不知道该用哪个了。

如果是申明,或者类型定义就没关系。

#8


因为申明和定义不会产生实体,所以放在头文件没关系。
在某个 cpp文件里再定义

Command CMD_PRINTER_RESET        = { 0x5F, 6,  3000 };

#9


非常感谢大家的回答,特别是xingzhe2001,解答的很精辟!
结贴。

#1


如果_MSC_VER<=1000呢

#2


CMD_RESET换个名字呢

#3


估计是与预定义的同名了。建议换一个名字试试

#4


char CMD_RESET[] = { STX, 0x5F, ETX, 0x5C };            // 打印机重置

不是头文件重复包含,而是你的工程里面应该还有一个CommDlg.h 或者cpp。
pos.h里面的这个定义CMD_RESET,和commDlg的重复了。

#5


情况是这样的:
我用的是MFC的对话框,我在工程中新建了一个新类CPos。




Pos.h
------------------------------------------------


#if !defined(AFX_POS_H__22F9CC51_D3E6_4A6D_AAEB_DFD8F78402FB__INCLUDED_)
#define AFX_POS_H__22F9CC51_D3E6_4A6D_AAEB_DFD8F78402FB__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <string>
using namespace std;

Command CMD_PRINTER_RESET        = { 0x5F, 6,  3000 };

...

#endif // !defined(AFX_POS_H__22F9CC51_D3E6_4A6D_AAEB_DFD8F78402FB__INCLUDED_)


Pos.cpp
-------------------------------------------

#include "stdafx.h"
#include "Comm.h"
#include "Pos.h"
#include "pcbdll.h"
#include <fstream>
using namespace std;


StdAfx.h
-------------------------------------------------
...
#include "pos.h"





其它对话框等cpp文件就没有包含pos.h文件了,都是向导生成的默认包含头文件,主要是包含stdafx.h。

请问我的问题出在哪呢?

谢谢!!

#6


头文件里只放声明,不要放定义(类定义除外)

#7


不要把全局变量的实现放在头文件里,头文件里应该放申明:

extern Command CMD_PRINTER_RESET;[code]

在某个cpp文件里再定义

[code=C/C++]Command CMD_PRINTER_RESET        = { 0x5F, 6,  3000 };


楼主理解错了#pragma once的意思, 
pragma once可以避免在一个cpp文件里引用俩次相同的头文件导致的重复定义。但是在不同的cpp里,两处引用都会起作用,所以就生成了两个全局的同名变量 CMD_PRINTER_RESET,编译器就不知道该用哪个了。

如果是申明,或者类型定义就没关系。

#8


因为申明和定义不会产生实体,所以放在头文件没关系。
在某个 cpp文件里再定义

Command CMD_PRINTER_RESET        = { 0x5F, 6,  3000 };

#9


非常感谢大家的回答,特别是xingzhe2001,解答的很精辟!
结贴。