C C 中的鏈結類問題整理

2021-09-23 01:47:13 字數 1477 閱讀 4773

以c++為例,假設有兩個功能a.cpp\b.cpp,以下為a.cpp對於的.**件(只做演示)

class a

;

b.**件如下

#include "a.h"

class b;

首先,建乙個main.cpp,具體如下

#include "a.h"

#include "b.h"

int main()

此處只用作演示上文提及的錯誤生成過程,所以啥也沒寫。

而當我們編譯的時候,神奇的事情出現了,編譯器彈出來這麼乙個錯誤:

由於vs現在已經有中文翻譯了,所以出現那個令人絕望的「redefined *** ...」已經不再出現,但是這個問題本身依然讓人覺得有點摸不著頭腦。實際上,這是由於c\c++編譯器在編譯的預處理階段是將include " .h"中的內容直接插入對應的.cpp檔案中,所以,既包含了"a.h",又包含了「b.h」的main.cpp中就會出現兩個a類,重定義即由此而來。

具體解決方法:

本文採用的是用**件中的巨集來解決這一問題,具體為在a.h中加入

#ifndef _a_h_

#define _a_h_

void f();

class a

;#endif // !_a_h_

使得a類值插入一次,因此解決了重定義的問題。

同樣,若在.**件中定義變數global,如

#ifndef _a_h_

#define _a_h_

int global;

void f();

class a

;#endif // !_a_h_

同時在a.cpp中寫乙個函式

#include "a.h"

void fun()

在進行編譯時出現了這樣乙個錯誤

又感覺很頭大啊,錯誤在**呢?

咱們來詳細看一下編譯發生的過程:

在上面我們不難發現,每個cpp檔案都是單獨編譯的,其只有到最後鏈結的時候才會在一起出現,結合上面的知識我們就知道了,每個包含include " a.h"的cpp都會生成乙個int global變數,但在編譯是各不影響,直到鏈結時才會出現「重定義」這一問題,這就是為什麼我們不能在.**件中定義變數,而要將全域性變數通過extern關鍵字甩出來的原因了。

寫在最後:這篇文章是從翁愷老師的c++課中總結出來的,儘管是一些在初學階段出現的問題,但其中展現出來的c\c++編譯器的相關知識卻非常深刻,聽完之後收益良多

C C 鏈結有關的問題

如果我們需要引用乙個外部庫裡面的變數或函式,要涉及到extern,具體該怎麼寫呢?下面是一小段例子函式 假設我們有2個原始檔hello.h和hello.cpp hello.h的 如下 ifdef cplusplus extern c endifhello.cpp的 如下 extern const c...

C C 中的 問題

符號是c c 之中非常有趣的,前段時間發現乙個很好玩的算式,在tc和vc下面獲得不同的結果。i 0 i i i i 熟悉c語言的能夠分析一下,首先是i 0,i的初值為0,第二步是很多個 號,我們大致可以推導下它的執行過程 先執行第乙個 i,i 1,然後 i,i 2,繼續 i,i 3,最後再進行 計算...

C C 中的堆和棧整理

一 預備知識 程式的記憶體分配 乙個由c c 編譯的程式占用的記憶體分為以下幾個部分 1 棧區 stack 由編譯器自動分配釋放 存放函式的引數值,區域性變數的值等。其操作方式類似於資料結構中的棧。2 堆區 heap 一般由程式設計師分配釋放,若程式設計師不釋放 程式結束時可能由os 注意它與資料結...