[英]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
的頭文件的內容包含在您的源代碼中。 這將為編譯器提供執行cin
、 cout
和許多其他相關功能的代碼。 這個文件的內容被聲明為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
組中的sort
或advance
函數的情況下編寫程序。 因此我不會包括頭文件algorithm
。
C++語言被設計成“用你所需要的”,換句話說,我們可以通過只包含我們需要的函數來創建小程序。
順便說一句,除了您正在使用的平台之外,還有許多其他平台。
某些平台需要適合小內存區域,並且可能沒有鍵盤或顯示器(例如嵌入式控制器)。
所以請記住,C++ 被定義為支持從小型受限系統到大型且幾乎不受約束的系統的平台。
因此,要求“僅包含您需要的內容”主題。
總之,由於 C++ 語言不會自動、神奇地提供整個庫的定義,包括模板庫,您需要告訴編譯器您要使用哪些函數組。 這允許更快的編譯,因為只指定了所需的頭文件。
注意:一些商店和圖書館用品喜歡使用Monolith包含系統。 這意味着他們有一個包含整個庫的包含文件,無論您使用一個函數還是多個函數。 windows.h
就是一個經典的例子。 一個不利因素是,當一個頭文件被更改時,所有內容都需要重新構建。 使用分離的包含文件,只需要重新構建包含更改的頭文件的組件。
預處理器指令 #include 的使用與 C++ 本身一樣古老。 它不會很快消失。在 C++ 命名空間中,不會將任何內容導入您的程序,它只是定義了特定頭文件功能的范圍。因此,兩者都是必需的。 單擊此處了解為什么要使用命名空間。
您的問題是: namespace std
具有iostream
庫的函數/類的所有定義。 因此,簡單地使用using namespace std
就足以調用或使用cout
或iostream
庫的所有其他功能。 為什么我們必須使用行#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所以它帶有編譯器,預建) iostream
您main.cpp
。 現在要使用位於main.cpp
std
命名空間下的iostream
函數或變量,我們必須使用作用域解析運算符 (::) 來告訴編譯器cout
、 cin
和iostream
其他功能位於std
命名空間。 因此我們簡單地寫成這樣: std::cin
和std::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.