0

我需要创建这样的结构:

// 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变量定义来修复,但这是一种艰难且错误的方式。

问题是:我该怎么办?

4

2 回答 2

2
int SomeVar; // used in first.cpp

永远不要在标题中定义变量。它们应该声明为extern

extern int SomeVar; // used in first.cpp

然后你可以在“first.cpp”中用int SomeVar;.


此外,“first.h”不需要包含“main.h”。仅当该标头中的定义绝对需要这些文件的内容时,标头应包含文件。“first.h”中的定义不需要“main.h”中的任何内容。因此,它不应该包括它。

如果“first.cpp”需要包含“second.h”中的某些内容,则“first.cpp”有责任包含它。

于 2011-07-15T11:12:20.423 回答
1

在头文件中使用extern关键字为:

//first.h
extern int SomeVar; //extern tells the compiler that definition is elsewhere

然后在.cpp文件中定义它并使用它:

//first.cpp
int SomeVar; //definition is here

至于SomeFunction,你自己定义了头文件吗?重新检查一下。:-)

于 2011-07-15T11:11:04.773 回答