預(yù)備知識(shí)
#include 就是把另一個(gè)文件里的東西復(fù)制到當(dāng)前文件,無(wú)論你的文件是. h 還是. cpp 都是一樣的。
c++中我們cpp文件和.h文件的區(qū)別是,cpp文件是需要編譯的文件,成為一個(gè)獨(dú)立的編譯單元,而h文件從來(lái)是不需要編譯,只是用于預(yù)處理。
在寫.h文件時(shí),可以在文件開始處寫上#pragma once,這條命令可以使同一個(gè)文件不會(huì)多次包含這個(gè).h文件的內(nèi)容了。
聲明只是告訴編譯器有這么一個(gè)東西,并不分配空間,定義會(huì)具體分配內(nèi)存空間。
外部變量
在同一個(gè)項(xiàng)目里,使用默認(rèn)的全局命名空間的情況下,如果在多個(gè)文件里定義同名全局變量(默認(rèn)情況下,全局變量是外部變量,可以被別的文件引用),則會(huì)導(dǎo)致這個(gè)名稱的變量的空間在不同編譯單位里被分配多次,而外部變量又是可以被其他文件引用的,從而在鏈接時(shí)導(dǎo)致錯(cuò)誤,鏈接器不知道哪個(gè)空間才是這個(gè)名稱的變量的正確地址。
在同一個(gè)項(xiàng)目里,使用同一個(gè)全局變量的方式是,只在一個(gè)文件里定義這個(gè)變量,而其他需要用到這個(gè)變量的文件,可以先聲明一下這個(gè)聲明,然后就可以使用這個(gè)變量了。
比如在test.cpp文件里寫如下代碼
int a=5;//定義變量a
在main.cpp文件里寫如下代碼
# include<iostream>
extern int a;//聲明變量a
//extern相當(dāng)于在和編譯器說(shuō),a已經(jīng)在別的地方定義了,去別的地方找它定義
int main()
{
std::cout<<a<<std::endl;
}
輸出結(jié)果為
5
外部函數(shù)
函數(shù)的代碼最后存放在虛擬內(nèi)存中的.text段里,在同一個(gè)項(xiàng)目里,使用默認(rèn)的全局命名空間的情況下,如果在多個(gè)文件里定義同名且參數(shù)一致的非成員函數(shù)(默認(rèn)情況下,非成員函數(shù)是外部函數(shù),可以被別的文件引用),則會(huì)導(dǎo)致這個(gè)名稱的非成員函數(shù)在不同編譯單位里有多個(gè)空間,從而在鏈接時(shí)導(dǎo)致錯(cuò)誤,鏈接器不知道哪個(gè)空間才是這個(gè)名稱的非成員函數(shù)的正確地址。
在同一個(gè)項(xiàng)目里,使用同一個(gè)非成員函數(shù)的方式是,只在一個(gè)文件里定義這個(gè)函數(shù),而其他需要用到這個(gè)函數(shù)的文件,可以先聲明一下這個(gè)聲明,然后就可以使用這個(gè)函數(shù)了。
在test.cpp文件寫如下代碼
#include <iostream>
void fun(){//定義函數(shù)fun
std::cout << "hello world" << std::endl;
}
在main.cpp寫如下代碼
void fun();//聲明函數(shù)fun,可省略extern
int main()
{
fun();//使用函數(shù)fun
}
輸出結(jié)果
hello world
類
C++類的定義,其實(shí)就是聲明一個(gè)類型,這個(gè)類型由哪些變量和函數(shù)組成,和我們通常所說(shuō)的定義不一樣,可以把它理解為變量的聲明。
而C++類的實(shí)現(xiàn),即定義類里面的成員函數(shù),所以可以把C++類的實(shí)現(xiàn)理解為變量的定義。
而默認(rèn)的全局命名空間情況下,變量是外部鏈接的,相似的,類也是外部鏈接的。
在test1.cpp內(nèi)容如下
class A{
public:
int a;
void fun();
};
main.cpp內(nèi)容如下
#include "test1.cpp"
#include <iostream>
void A::fun() {
std::cout<<"hello world"<<std::endl;
}
int main()
{
A temp;
temp.fun();
}
輸出結(jié)果
hello world
相當(dāng)于在test1.cpp和main.cpp先聲明了類 A,再在main.cpp里面定義這個(gè)類A(具體實(shí)現(xiàn)這個(gè)類A)。如果在test1.cpp里不但聲明了A,還實(shí)現(xiàn)了A,則會(huì)造成重定義錯(cuò)誤。
所以項(xiàng)目的組織方式是,需要被多個(gè)文件用到的變量聲明,類的聲明和函數(shù)聲明放在頭文件里,聲明可以存放在多個(gè)不同的文件里,這些文件使用#include"*.h"來(lái)包含這些頭文件。而這些變量的定義和函數(shù)定義和類的實(shí)現(xiàn)(可以理解為定義)在某個(gè).cpp里實(shí)現(xiàn),定義只需要定義一次。