2015-04-02 56 views
1

因爲我還在學習,並且正在拉我的頭髮,試圖弄清楚爲什麼我的鏈接器不斷給我提出問題,我一直在測試一些東西。one.cpp和two.cpp都包括#include two.h

這裏就是我所做的:

  • 製作one.cpp並宣佈INT myVar的。

  • 製作two.cpp並將其留空。

  • make two.h並聲明int myVar。

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

當我嘗試構建它時,我的鏈接器說int myVar已經被定義。

我知道你只能定義一次東西,但在這種情況下,我沒有雙重定義任何東西,只是聲明瞭它們。

編輯:如果我將'extern'關鍵字添加到two.h中的int myVar,它可以工作,但爲什麼我必須?我真的不理解這是如何工作的。

編輯(很長一段時間後):我實際上多次定義相同的變量。

+0

我覺得我更接近答案。 one.cpp包含two.h(它具有var_b的聲明),所以one.cpp具有var_b的聲明。然後two.cpp包含two.h文件中的var_b聲明。那麼,當需要鏈接兩個obj文件時,其中一個已經有了聲明,並且正在鏈接另一個?但是我認爲你可以根據需要多次申報,但是沒有定義多次? – Zebrafish 2015-04-02 16:07:43

回答

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