我需要创建这样的结构:
// file main.h:
#pragma once
#ifndef _MAIN_H
#define _MAIN_H
#include <iostream>
#include "first.h"
#include "second.h"
#endif
// -----------------
// file first.h:
#pragma once
#ifndef _FIRST_H
#define _FIRST_H
#include "main.h" // because of using SomeFunction() in first.cpp
int SomeVar; // used in first.cpp
#endif
// -----------------
// file second.h:
#pragma once
#ifndef _SECOND_H
#define _SECOND_H
#include "main.h" // because of using SomeVar in second.cpp
int SomeFunction(); // implemented in second.cpp
#endif
// -----------------
按照逻辑,如果main.h
将首先编译,那么每个头文件将只包含一次,并且所有变量/函数都将正常定义。
例如,此配置在 IAR C++ 编译器中正常编译,如果在选项“预包含文件”(未预编译)中设置为main.h
.
但是,在 Visual Studio 2010 中,相同的结构会导致链接器错误,例如:
1>second.obj : error LNK2005: "int SomeVar" (?SomeVar@@3HA) already defined in first.obj
1>second.obj : error LNK2005: "int SomeFunction" (?SomeFunction@@3HA) already defined in first.obj
我认为是因为按字母顺序包含文件。显然,链接器忽略了pragma-和define-guards。
错误可以通过额外的标头和external
变量定义来修复,但这是一种艰难且错误的方式。
问题是:我该怎么办?