欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

c++ 防止頭文件重復(fù)引入的三種方法

 更新時(shí)間:2021年02月25日 16:40:18   作者:C語(yǔ)言編程學(xué)習(xí)基地  
這篇文章主要介紹了c++ 防止頭文件重復(fù)引入的三種方法,幫助大家更好的理解和學(xué)習(xí)使用c++,感興趣的朋友可以了解下

在之前我們?cè)敿?xì)介紹了 C 語(yǔ)言中如何使用宏定義(#ifndef / #define / #endif)來(lái)有效避免頭文件被重復(fù) #include,此方式在 C++ 多文件編程中也很常用。

舉個(gè)例子,如下是一個(gè) C++ 項(xiàng)目,其內(nèi)部含有 school.h 和 student.h 這 2 個(gè)頭文件以及 main.cpp 源文件,其各自包含的代碼為:

//student.h

class Student {

    //......

};

//school.h

#include "student.h"

class School {

    //......

private:

    Student stu[50];

};

//main.cpp

#include "student.h"

#include "school.h"

int main() {

    //......

    return 0;

}

運(yùn)行此項(xiàng)目會(huì)發(fā)現(xiàn),編譯器報(bào)“Student 類(lèi)型重定義”錯(cuò)誤。這是因?yàn)樵?school.h 文件中已經(jīng) #include 了一次 "student.h",而在 main.cpp 主程序又同時(shí) #include 了 "school.h" 和 "student.h",即 Student 類(lèi)的定義被引入了 2 次,C++不允許同一個(gè)類(lèi)被重復(fù)定義。

有小伙伴可能想到,既然 School.h 文件中已經(jīng)引入了 Student 類(lèi),那去掉 main.cpp 主程序引入的 student.h 文件不就可以了嗎?這樣確實(shí)可以避免重復(fù)引入 Student 類(lèi),但此方式并不適用于所有“重復(fù)引入”的場(chǎng)景。

C++ 多文件編程中,處理“多次 #include 導(dǎo)致重復(fù)引入”問(wèn)題的方式有以下 3 種。

————————

1) 使用宏定義避免重復(fù)引入

在實(shí)際多文件開(kāi)發(fā)中,我們往往使用如下的宏定義來(lái)避免發(fā)生重復(fù)引入:

#ifndef _NAME_H

#define _NAME_H

//頭文件內(nèi)容

#endif

其中,_NAME_H 是宏的名稱(chēng)。需要注意的是,這里設(shè)置的宏名必須是獨(dú)一無(wú)二的,不要和項(xiàng)目中其他宏的名稱(chēng)相同。

當(dāng)程序中第一次 #include 該文件時(shí),由于 _NAME_H 尚未定義,所以會(huì)定義 _NAME_H 并執(zhí)行“頭文件內(nèi)容”部分的代碼;當(dāng)發(fā)生多次 #include 時(shí),因?yàn)榍懊嬉呀?jīng)定義了 _NAME_H,所以不會(huì)再重復(fù)執(zhí)行“頭文件內(nèi)容”部分的代碼。

也就是說(shuō),我們可以將前面項(xiàng)目中的 student.h 文件做如下修改:

#ifndef _STUDENT_H

#define _STUDENT_H

class Student {

    //......

};

#endif

雖然該項(xiàng)目 main.cpp 文件中仍 #include 了 2 次 "student.h",但鑒于 _STUDENT_H 宏只能定義一次,所以 Student 類(lèi)也僅會(huì)定義一次。再次執(zhí)行該項(xiàng)目會(huì)發(fā)現(xiàn),其可以正常執(zhí)行。

2) 使用#pragma once避免重復(fù)引入

除了前面第一種最常用的方式之外,還可以使用 #pragma one 指令,將其附加到指定文件的最開(kāi)頭位置,則該文件就只會(huì)被 #include 一次。

我們知道,#ifndef 是通過(guò)定義獨(dú)一無(wú)二的宏來(lái)避免重復(fù)引入的,這意味著每次引入頭文件都要進(jìn)行識(shí)別,所以效率不高。但考慮到 C 和 C++ 都支持宏定義,所以項(xiàng)目中使用 #ifndef 規(guī)避可能出現(xiàn)的“頭文件重復(fù)引入”問(wèn)題,不會(huì)影響項(xiàng)目的可移植性。

和 ifndef 相比,#pragma once 不涉及宏定義,當(dāng)編譯器遇到它時(shí)就會(huì)立刻知道當(dāng)前文件只引入一次,所以效率很高。

但值得一提的是,并不是每個(gè)版本的編譯器都能識(shí)別 #pragma once 指令,一些較老版本的編譯器就不支持該指令(執(zhí)行時(shí)會(huì)發(fā)出警告,但編譯會(huì)繼續(xù)進(jìn)行),即 #pragma once 指令的兼容性不是很好。

目前,幾乎所有常見(jiàn)的編譯器都支持 #pragma once 指令,甚至于 Visual Studio 2017 新建頭文件時(shí)就會(huì)自帶該指令??梢赃@么說(shuō),在 C/C++ 中,#pragma once 是一個(gè)非標(biāo)準(zhǔn)但卻逐漸被很多編譯器支持的指令。

除此之外,#pragma once 只能作用于某個(gè)具體的文件,而無(wú)法向 #ifndef 那樣僅作用于指定的一段代碼。

這里仍以前面的 "student.h" 文件為例,將其內(nèi)容修改為:

#pragma once

class Student {

    //......

};

3) 使用_Pragma操作符

C99 標(biāo)準(zhǔn)中新增加了一個(gè)和 #pragma 指令類(lèi)似的 _Pragma 操作符,其可以看做是 #pragma 的增強(qiáng)版,不僅可以實(shí)現(xiàn) #pragma 所有的功能,更重要的是,_Pragma 還能和宏搭配使用。

有關(guān) _Pragma 操作符更多的功能和用法,本節(jié)不做詳細(xì)講解,這里僅介紹如何用 _Pragma 操作符避免頭文件重復(fù)引入。

當(dāng)處理頭文件重復(fù)引入問(wèn)題時(shí),可以將如下語(yǔ)句添加到相應(yīng)文件的開(kāi)頭:

_Pragma("once")

比如,將該語(yǔ)句添加到前面項(xiàng)目中 student.h 文件中的開(kāi)頭位置,再次執(zhí)行項(xiàng)目,其可以正常執(zhí)行。

事實(shí)上,無(wú)論是 C 語(yǔ)言還是 C++,為防止用戶(hù)重復(fù)引入系統(tǒng)庫(kù)文件,幾乎所有庫(kù)文件中都采用了以上 3 種結(jié)構(gòu)中的一種,這也是為什么重復(fù)引入系統(tǒng)庫(kù)文件編譯器也不會(huì)報(bào)錯(cuò)的原因。

總結(jié)

本節(jié)介紹了 3 種避免頭文件被重復(fù)引入的方法,其中 #pragma once 和 _Pragma("once") 可算作一類(lèi),其特點(diǎn)是編譯效率高,但可移植性差(編譯器不支持,會(huì)發(fā)出警告,但不會(huì)中斷程序的執(zhí)行);而 #ifndef 的特點(diǎn)是可移植性高,編譯效率差。讀者可根據(jù)實(shí)際情況,挑選最符合實(shí)際需要的解決方案。

除非對(duì)項(xiàng)目的編譯效率有嚴(yán)格的要求,強(qiáng)烈推薦讀者選用第一種解決方案,即采用 #ifndef / #define / #endif 組合解決頭文件被重復(fù)引入。

另外在某些場(chǎng)景中,考慮到編譯效率和可移植性,#pragma once 和 #ifndef 經(jīng)常被結(jié)合使用來(lái)避免頭文件被重復(fù)引入。比如說(shuō):

#pragma once

#ifndef _STUDENT_H

#define _STUDENT_H

class Student {

    //......

};

#endif

當(dāng)編譯器可以識(shí)別 #pragma once 時(shí),則整個(gè)文件僅被編譯一次;反之,即便編譯器不識(shí)別 #pragma once 指令,此時(shí)仍有 #ifndef 在發(fā)揮作用。

以上就是c++ 防止頭文件重復(fù)引入的三種方法的詳細(xì)內(nèi)容,更多關(guān)于c++ 頭文件重復(fù)引入的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • VC++開(kāi)發(fā)中完美解決頭文件相互包含問(wèn)題的方法解析

    VC++開(kāi)發(fā)中完美解決頭文件相互包含問(wèn)題的方法解析

    本文中,為了敘述方便,把class AClass;語(yǔ)句成為類(lèi)AClass的聲明,把class AClass開(kāi)始的對(duì)AClass的類(lèi)成員變量、成員函數(shù)原型等的說(shuō)明稱(chēng)為類(lèi)的定義,而把在CPP中的部分稱(chēng)為類(lèi)的定義
    2013-09-09
  • 解析C++ 浮點(diǎn)數(shù)的格式化輸出

    解析C++ 浮點(diǎn)數(shù)的格式化輸出

    本篇文章是對(duì)C++中浮點(diǎn)數(shù)的格式化輸出進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • Linux下g++編譯與使用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的方法

    Linux下g++編譯與使用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的方法

    下面小編就為大家?guī)?lái)一篇Linux下g++編譯與使用靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • C語(yǔ)言 數(shù)據(jù)類(lèi)型詳細(xì)介紹

    C語(yǔ)言 數(shù)據(jù)類(lèi)型詳細(xì)介紹

    本文主要講解C語(yǔ)言 數(shù)據(jù)類(lèi)型,這里整理了詳細(xì)的數(shù)據(jù)類(lèi)型的資料,希望能幫助剛剛開(kāi)始學(xué)習(xí)C語(yǔ)言的同學(xué)
    2016-08-08
  • C語(yǔ)言進(jìn)階練習(xí)二叉樹(shù)的遞歸遍歷

    C語(yǔ)言進(jìn)階練習(xí)二叉樹(shù)的遞歸遍歷

    樹(shù)是一種重要的非線性數(shù)據(jù)結(jié)構(gòu),直觀地看,它是數(shù)據(jù)元素(在樹(shù)中稱(chēng)為結(jié)點(diǎn))按分支關(guān)系組織起來(lái)的結(jié)構(gòu),很象自然界中的樹(shù)那樣。樹(shù)結(jié)構(gòu)在客觀世界中廣泛存在,如人類(lèi)社會(huì)的族譜和各種社會(huì)組織機(jī)構(gòu)都可用樹(shù)形象表示,本篇介紹二叉樹(shù)的遞歸與非遞歸遍歷的方法
    2022-06-06
  • C語(yǔ)言實(shí)現(xiàn)在控制臺(tái)打印余弦曲線

    C語(yǔ)言實(shí)現(xiàn)在控制臺(tái)打印余弦曲線

    余弦曲線又叫余弦波(cosinwave),是一種來(lái)自數(shù)學(xué)三角函數(shù)中的余弦比例的曲線。這篇文章主要為大家介紹了如何在控制臺(tái)繪制余弦曲線,感興趣的可以了解一下
    2023-02-02
  • QT連接Mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)步驟

    QT連接Mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)步驟

    本文主要介紹了QT連接Mysql數(shù)據(jù)庫(kù)的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • C++讀寫(xiě)Excel的實(shí)現(xiàn)方法詳解

    C++讀寫(xiě)Excel的實(shí)現(xiàn)方法詳解

    本篇文章是對(duì)C++讀寫(xiě)Excel的實(shí)現(xiàn)方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C語(yǔ)言中結(jié)構(gòu)體和共用體實(shí)例教程

    C語(yǔ)言中結(jié)構(gòu)體和共用體實(shí)例教程

    這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中結(jié)構(gòu)體和共用體的相關(guān)資料,結(jié)構(gòu)體是一種自定義的復(fù)合數(shù)據(jù)類(lèi)型,共用體也叫聯(lián)合體,使幾個(gè)不同類(lèi)型的變量共占一段內(nèi)存(相互覆蓋),需要的朋友可以參考下
    2021-06-06
  • C語(yǔ)言動(dòng)態(tài)內(nèi)存管理malloc柔性數(shù)組示例詳解

    C語(yǔ)言動(dòng)態(tài)內(nèi)存管理malloc柔性數(shù)組示例詳解

    這篇文章主要為大家介紹了C語(yǔ)言動(dòng)態(tài)內(nèi)存管理malloc柔性數(shù)組示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10

最新評(píng)論