簡體   English   中英

為什么我要包含頭文件<iostream>使用命名空間 std 后?

[英]why should i include the header file <iostream> after using the namespace std?

既然命名空間 std 已經有包含函數定義的 C++ 庫(如果我是對的),那么我們為什么要在它上面包含頭文件??。 由於命名空間 std 包括 c++ 標准庫,我認為沒有理由單獨包括它的聲明。

當您執行#include <iostream>它會導致一組類和其他內容包含在您的源文件中。 對於 iostream 和大多數標准庫頭文件,它們將這些東西放在名為std的命名空間中。

所以#include <iostream>的代碼看起來像這樣:

namespace std { 
    class cin  { ... };
    class cout { ... };
    class cerr { ... };
    class clog { ... };
    ...
}

所以此時,你可以編寫一個如下所示的程序:

#include <iostream>

int main() {
    std::cout << "hello\n";
    return 0;
}

現在,有些人覺得std::cout太冗長了。 所以他們這樣做:

#include <iostream>
using namespace std;

int main() {
    cout << "hello\n";
    return 0;
}

就個人而言,我不建議這樣做,如果您真的覺得std::cout太冗長,那么我建議您使用較小的using語句。

#include <iostream>
using std::cout;

int main() {
    cout << "hello\n";
    return 0;
}

如果您想知道為什么我不建議using namespace std ,那么我會將您轉至以下有關 stackoverflow 的另外兩篇文章:

編譯器本身沒有任何命名空間(無論是std還是其他命名空間)中事物的定義。 那就是源文件和頭文件的作用。

什么using namespace std; 告訴編譯器是“如果您在當前命名空間中找不到某個名稱,也請查看std命名空間”。

#include <iostream>告訴編譯器您希望將名為iostream的頭文件的內容包含在您的源代碼中。 這將為編譯器提供執行cincout和許多其他相關功能的代碼。 這個文件的內容被聲明為namespace std { ... all the stuff goes here ... }

命名空間的使用允許其他人在namespace math;工作namespace math; 不必擔心“嗯,我現在該怎么辦,我需要一個入口數量的計數器,讓我們稱之為cin - 但是等等,它在任何地方都使用過嗎?”。

這可能不是最好的例子,但在大型項目中,跟蹤事物及其名稱變得越來越困難。 而 C++ 是一種用於數百萬行代碼的大型項目的語言 - 現在它開始變得難以記住您是否使用過特定名稱。 命名空間確保您不必在特定命名空間之外擔心它。

(哦,在我的代碼中,我傾向於不使用using namespace std; ,而是寫std::cout << "Hello, World!" << std::endl; - 這有助於說明cout我'我在這里使用的是std ,而不是其他東西。當您有多個具有相似內容的命名空間時,這特別有用,例如在我自己的編譯器中,我的編譯器具有它的功能, std命名空間提供了一些東西,以及llvm編譯器的事情 - 如果我堅持using namespace llvm;在代碼的開頭,很難跟蹤Type* p = ... ; 是來自 LLVM 還是我自己代碼的某些部分。)

...為什么我們在它上面包含頭文件???

是的,這里有一些很大的混亂。

命名空間

命名空間是一種對函數名稱等符號進行分類或分組的方法。

命名空間旨在防止不同軟件組件(例如庫)之間的名稱沖突。

作為標准語言一部分的函數被分組在命名空間std

C++ 語言提供了在使用命名空間時減少輸入量的語句。 其中之一是using語句。

頭(包括)文件

編寫程序時,編譯器不需要自動包含所有符號定義,例如函數聲明。 您需要告訴它您計划使用哪些功能。

例如,我可以在不使用algorithm組中的sortadvance函數的情況下編寫程序。 因此我不會包括頭文件algorithm

C++語言被設計成“用你所需要的”,換句話說,我們可以通過只包含我們需要的函數來創建小程序。

其他平台

順便說一句,除了您正在使用的平台之外,還有許多其他平台。

某些平台需要適合小內存區域,並且可能沒有鍵盤或顯示器(例如嵌入式控制器)。

所以請記住,C++ 被定義為支持從小型受限系統到大型且幾乎不受約束的系統的平台。

因此,要求“僅包含您需要的內容”主題。

概括

總之,由於 C++ 語言不會自動、神奇地提供整個庫的定義,包括模板庫,您需要告訴編譯器您要使用哪些函數組。 這允許更快的編譯,因為只指定了所需的頭文件。

注意:一些商店和圖書館用品喜歡使用Monolith包含系統。 這意味着他們有一個包含整個庫的包含文件,無論您使用一個函數還是多個函數。 windows.h就是一個經典的例子。 一個不利因素是,當一個頭文件被更改時,所有內容都需要重新構建。 使用分離的包含文件,只需要重新構建包含更改的頭文件的組件。

預處理器指令 #include 的使用與 C++ 本身一樣古老。 它不會很快消失。在 C++ 命名空間中,不會將任何內容導入您的程序,它只是定義了特定頭文件功能的范圍。因此,兩者都是必需的。 單擊此處了解為什么要使用命名空間。

您的問題是: namespace std具有iostream庫的函數/類的所有定義。 因此,簡單地使用using namespace std就足以調用或使用coutiostream庫的所有其他功能。 為什么我們必須使用行#include <iostream> 似乎是多余的。

粗略地我們可以認為iostream庫有兩個文件:頭文件和實現/源文件。 這兩個文件有一個名為std的命名空間。 頭文件僅包含iostream庫將要使用的類或函數或變量的聲明或前向聲明,並且這些聲明或前向聲明位於std命名空間下。 實現文件包含類或函數或變量的實際實現,這些實現在std命名空間下; 該文件也稱為源文件。

所以,如果你只使用using namespace std沒有#include <iostream>在你main.cpp文件的編譯器將搜索std命名空間在你main.cpp文件,但它是不是在這里。 你會得到編譯器錯誤。

現在,如果您在main.cpp包含此#include <iostream>行,預處理器將轉到iostream的頭文件並將std命名空間及其代碼復制到我們的main.cpp 和連接器將鏈接預編譯(如iostream源/執行文件是一個SLT所以它帶有編譯器,預建) iostreammain.cpp 現在要使用位於main.cpp std命名空間下的iostream函數或變量,我們必須使用作用域解析運算符 (::) 來告訴編譯器coutciniostream其他功能位於std命名空間。 因此我們簡單地寫成這樣: std::cinstd::cout

現在鍵入std::對某些人來說似乎是多余的,所以他們通過使用using namespace std告訴編譯器“嘿編譯器,如果在全局/當前命名空間中找不到任何變量/函數/類,請查看std命名空間。” 雖然這不是最佳實踐,但這是另一個要討論的話題。 因此,你的假設,即std命名空間包含的所有SLT公司的C函數/類/變量++所有的定義是不是在大多數情況下是正確的,但std的命名空間只包含來自STL的聲明是正確的假設。

這是如何將iostream libray 添加到我們的代碼文件中的虛擬實現: iostream.h

// This is header file that only contains the
// functions declarations.
namespace std_dum
{
    int add(int x, int y);

    int mult(int x, int y);
}

iostream_dum.cpp :

// This is source file of iostream_dum.h header
// which contains the implementation of functions.

#include "iostream_dum.h"

namespace std_dum
{

    int add(int x, int y)
    {
        return x + y;
    }

    int mult(int x, int y)
    {
        return x * y; 
    }

}

main.cpp :

#include <iostream>
#include "iostream_dum.h"

int main()
{
    std::cout << std_dum::add(100, 200) << '\n';
    std::cout << std_dum::mult(100, 200) << '\n';

    return 0;
}

要查看預處理后我們的main.cpp文件會發生什么,請運行以下命令: g++ -E main.cpp iostream_dum.cpp

這里大概是我們的main.cpp樣子:

namespace std_dum
{
    int add(int x, int y);

    int mult(int x, int y);
}

int main()
{
 std::cout << std_dum::add(100, 200) << '\n';
 std::cout << std_dum::mult(100, 200) << '\n';

 return 0;
}

namespace std_dum
{

    int add(int x, int y)
    {
        return x + y;
    }

    int mult(int x, int y)
    {
        return x * y;
    }

 }

為了清楚起見,我丟棄了預處理器從#include <iostream>復制的所有代碼。

現在應該很清楚了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM