one.cpp和two.cpp都是#include two.h

时间:2015-04-02 15:04:49

标签: c++ c header

因为我还在学习并且正在试图弄清楚为什么我的链接器一直给我带来问题,我一直在测试一些东西。

这就是我的所作所为:

  • 制作one.cpp并声明int myVar。

  • 制作two.cpp并将其留空。

  • 制作two.h并声明int myVar。

  • 在one.cpp和two.cpp中包含two.h。

当我尝试构建它时,我的链接器说已经定义了my myVar。

我知道你只能定义一次东西,但在这种情况下我没有定义任何东西,只是声明了它们。

编辑:如果我添加' extern'关键字to two myVar在two.h中有效,但我为什么要这样做?我真的不明白这是如何运作的。

编辑(很久以后):我实际上是多次定义同一个变量。

1 个答案:

答案 0 :(得分:3)

很久以后,我已经理解了这个问题。当你这样做时:

int a;    // <--- This is a definition, not just a declaration

事实证明,C ++中有一个非常精细的规则系统,关于什么构成定义或声明。

以下是大纲:

//  VARIABLES / BUILT-IN TYPES / PRIMITIVE DATA TYPES
int anInt;          // A definition
int anInt;          // Error, multiply defined variable, whether in same .cpp or another
extern int anInt;   // A declaration
extern int anInt;   // Fine, declare how often you like
int* pToInt         // A definition
extern int* pToInt  // A declaration
                    // Other types such as enums, references, etc. also fall in this category

// FUNCTIONS
// Keyword 'extern' is optional or doesn't do anything before a function declaration / signature without a body. Functions without a body can be declared as many times as you want, just like extern variables. Note, placing the 'inline' keyword before the function allows you to define it in multiple places. If multiply defined in the same cpp it must have the same implementation, otherwise the compiler won't notice different implementations in different cpps. This is confusing.
void shootSoldier();        // Function declaration, also signature or prototype
extern void shootSoldier(); // 'extern' keyword here makes no difference, it's optional
void shootSoldier();        // Same function can be declared again, no problem
void shootSoldier() {}      // Function has a function body, meaning it's defined.
void shootSoldier() {}      // Error: multiple definitions for function

// CLASSES / STRUCTS / USER-DEFINED TYPES
// Keyword 'extern' I'm pretty sure is optional or doesn't do anything before one of these types that doesn't have squiggly brackets, ie., isn't defined
struct Animal;          // Declaration of a type
extern struct Animal;   // No difference, declaration of a type
struct Animal;          // Repeated declaration, no problem
struct Animal{ string colour; }; // Definition of a type

//There is an extra rule with this last category. This category is most similar to the function category, but whereas functions can only be defined once in your program (meaning having a function body), with this category, classes, structs etc, you can only redefine it in another compilation unit, ie., another.cpp file.
// So:

struct Animal { string colour; };
struct Animal { string colour; };   //   Only allowed to redefine in another .cpp file

// Strangely, this seems to mean you can 'redefine' these types, meaning an exemption from the one definition rule (ODR).
// Then there's a whole mess of ifs and buts, like the fact that your class is defined, but the member function that it contains is only declared.
// There's no doubt more exceptions and subleties that I don't get.
// This topic has been covered a few times here at Stack Overflow.

http://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration