91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么理解C++內鏈接與外鏈接

發布時間:2021-11-17 11:07:27 來源:億速云 閱讀:191 作者:iii 欄目:開發技術

本篇內容主要講解“怎么理解C++內鏈接與外鏈接”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么理解C++內鏈接與外鏈接”吧!

首先理解什么是編譯單元?

我們知道,其實編譯器在編譯代碼時,只會去編譯.cpp格式的源文件,并且預編譯器會遞歸的把.cpp所有#include的頭文件都“拷貝”到.cpp文件中去,之后對這個文件再進行編譯,生成二進制的.obj文件。那么其實每一個.cpp文件都是一個編譯單元。

聲明與定義

一個聲明將一個名稱引入一個作用域,C++中在同一個作用域中可以重復聲明,除了類中的成員函數與成員變量的聲明。以下都是聲明:

Extern int number; //外部引用聲明

Typedef int  int32; // typedef聲明

Class A;          //類的前置聲明

Using std::cin;   //名字空間引用聲明

Friend f;         //友元聲明

Int testFun();    //函數前置聲明

定義決定了一個實體在一個作用域的唯一描述,同一作用域不可以重復定義一個實體。以下都是定義:

Int a;

Class Myclass{…};

Myclass ma;

Static int b;

Enum{first, second,third};

Const int m = 2;

Void hello(){…}

什么是內部鏈接?

如果一個名稱對于他的編譯單元是局部的,并且在鏈接時不會與其他的編譯單元中同樣的名字沖突,那么這個名稱就擁有內部鏈接。這個實體有內部鏈接,他就不會與其他.cpp文件同名的實體沖突。換個說法,那些編譯單元(.cpp)中不能向其他編譯單元(.cpp)展示提供其定義的函數、變量就擁有內部鏈接

那么哪些實體擁有內部鏈接?

1.      靜態(static)全局變量,自由函數,友元函數定義

2.      類的定義

3.      內聯函數定義

4.      Union共用體定義

5.      名字空間的const常量定義

6.      枚舉類型定義

7.      所有的聲明(有人將聲明歸結為無鏈接)

什么是外部鏈接?

一個多文件的程序中,一個實體可以在鏈接時與其他編譯單元交互,那么這個實體就擁有外部鏈接。

換個說法,那些編譯單元(.cpp)中能想其他編譯單元(.cpp)提供其定義,讓其他編譯單元(.cpp)使用的函數、變量就擁有外部鏈接

那么哪些實體擁有外部鏈接?

1.      類的非內聯函數(包括成員函數和靜態類成員函數)的定義

2.      類的靜態成員變量的定義

3.      名字空間或全局的非靜態的自由函數,非靜態變量,非友元函數的定義

那么這里總結一下,定義這樣的內鏈接與外鏈接有什么意義?

所謂鏈接,就是因為項目工程的不斷擴大,寫在一個.cpp文件即難以維護,又不好去合作開發。所以去將代碼按照比較有條理的,分成多個文件,讓其可以獨立編譯,在最后運行在整合到一起,也就是通過鏈接再去找到需要的代碼。這時候就需要外鏈接定位到合適的代碼。

比如我們定義的全局函數和變量,可以跨模塊的鏈接使用。

有一些名字定義所表示的實體擁有外部鏈接,這樣就意味著他可以跨越編譯單元去進行代碼的鏈接。所以,擁有外部鏈接的實體如果被聲明在頭文件并且被多個.cpp文件包含,可能就會出現鏈接沖突錯誤,因為每個包含這個擁有外部鏈接實體的.cpp都會分配空間,當多個編譯單元鏈接的時候,連接器就會面對多個相同的名字,無法正常鏈接到正確的對象。

下面舉個例子:(VS2012環境下)

//lesson.h

namespace lesson

{
         int  test;

}

//lesson.cpp

#include "stdafx.h"

#include "lesson.h"

int _tmain(intargc,_TCHAR*argv[])

{
         system("pause");

         return0;

}

//test.cpp

#include "lesson.h"

我們就會看到

error LNK2005: "intlesson::test" (?test@lesson@@3HA) 已經在 lesson.obj 中定義C:\Users\user\Documents\Visual Studio 2012\Projects\lesson\lesson\stdafx.obj

這樣的錯誤提示。

而對于擁有內部鏈接的實體則不會出現這樣的情況,因為他不會與其他.cpp的同名實體產生沖突。比如我們將上面的lesson.h改為

//lesson.h

class lesson

{
         int  test;

}

這樣就不會有任何錯誤,因為類的定義是有內部鏈接的。

如果在lesson.h里面再定義靜態變量,枚舉類,進行各種聲明等,這些實體由于有內部鏈接所以仍然是合法的,編譯器會認為你想在各個編譯單元中都有一個私有的副本。

那么進一步的概括這些內容就是一句話  

相同作用域內的聲明可以有多個,但是只能定義一次。

先不考慮內鏈接還是外鏈接,我們都知道一個{}里面不可能定義兩個一模一樣的名字。對于一個單獨的.cpp文件,我們是知道的,但是對于多個文件,好像就稍微有點暈。其實,這是一個道理,我們的外部鏈接就是讓各個.cpp文件能鏈接到一起,這樣在.cpp文件遇到第一個{}之前,他們的作用域就可以理解為相同的,所以擁有外部鏈接的實體(全局函數,變量等)出現在第一個{}之前,而且名字相同,那就是出現了定義重復的錯誤。

我們再看,所有的聲明都是有內部鏈接的,然而他其實可以鏈接到其他文件,因為他的定義是在其他的編譯單元的,所以多個編譯單元擁有相同的聲明也是合理的。但是,我們知道,這個聲明對應的定義肯定只有一個。

最后再給出一個C++編程建議,慎重考慮在頭文件中定義有鏈接的實體

一,如果頭文件是像int a=1;這樣的定義,被包含在多個.cpp文件后肯定會報出鏈接錯誤。

二,如果是想static int a = 2;這樣的定義就會在所有包含他的.cpp文件中生成一個副本,如果被大量源文件include的話,就會占據大量的空間,造成內存浪費。

到此,相信大家對“怎么理解C++內鏈接與外鏈接”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

c++
AI

错那县| 徐汇区| 涿州市| 图们市| 清流县| 安吉县| 江津市| 如东县| 保靖县| 射阳县| 桂平市| 沿河| 郎溪县| 黄平县| 博客| 安溪县| 南通市| 新化县| 兴义市| 和平区| 阜平县| 阿瓦提县| 涿州市| 阳原县| 扎兰屯市| 达拉特旗| 尉犁县| 益阳市| 江都市| 津南区| 临颍县| 陵川县| 镇康县| 九江市| 贵德县| 淮滨县| 阳原县| 英山县| 营山县| 西城区| 绵阳市|