2013-05-27 59 views
3

我一直認爲,如果你做#include <cheader>(其中header就像STDIO/STDLIB /串一些標準C++頭),它是相同的是#include <header.h>,但裹入std命名空間。那麼代碼片段如何編譯(g ++ 4.7.3)?爲什麼使用<cheader>代替<header.h>?

#include <cstdlib> 
int main() 
{ 
    malloc(1); 
    return 0; 
} 

爲什麼一個包括<cstdio>然後(而不是<stdio.h>)如果標準C函數將在全局命名空間呢?

而第二個問題是 - 我應該怎麼做才能一些功能進行全局命名空間的(同時使用C++頭文件在同一時間)?舉例來說,我不想malloc是在全局命名空間,因爲我有一個家庭作業:寫我自己的內存分配器(特別是mallocfree功能),我會編譯成動態庫,並使用插入任何程序LD_PRELOAD

+1

因爲不幸的是,實現*允許*名稱在'std ::'名稱空間之外,以及* required *在它們之內。 – juanchopanza

+0

@juanchopanza但如果我們允許標準頭文件混淆全局名稱空間,那麼使用名稱空間'std'有什麼意義? – karlicoss

+0

@ karlicoss!這就是爲什麼我認爲這是「不幸」。它僅適用於來自標準C庫的名稱。所有標準的C++函數和類型都在'std ::'命名空間中。 – juanchopanza

回答

4

如何的代碼片斷然後編譯(克++ 4.7.3)?

因爲C++ 11標準規定的17.6.1.2/4:

[...]這是 不確定是否這些名稱是全局命名空間範圍內的第一個聲明,然後通過明確注入 到名字空間std使用申述(7.3.3)。

因此,允許實現在全局名稱空間中定義這些實體。

爲什麼要包括那麼(而不是)如果標準C函數將在全局命名空間呢?

首先,作爲良好的作風問題。包括<stdio.h>給你確定性所有的實體在全局命名空間中定義,而包括<cstdio>給你的肯定,這些實體是一個你可以(在std命名空間),與可能(但不是一定)這些名稱也可能出現在全局名稱空間中,這是不必要的缺點。

我應該怎麼做才能從全局命名空間中獲取這些功能(同時使用C++頭文件)?

不幸的是,你不能讓一個實體了它生活在命名空間的。但是你可以(從您的實現罵開)做的是避免使用標準C函數完全,並且更喜歡使用從功能C++標準庫。這些保證住在std命名空間。

因此,舉例來說,如果你必須執行低級別的內存管理,而不是使用mallocnew操作。另外,請注意「必須對」的強調:大多數情況下,您應該使用RAII封裝(如智能指針或標準容器),以避免必須應對低級內存管理,即newdelete

+0

是的,如果我必須編寫一些C++應用程序,我肯定會使用'new'運算符,RAII和其他東西。但是,我必須編寫內存分配器,其他程序(如'gcc'或'vim'等二進制文件)將使用該分配器。我只能使用非常低級別的內存抽象,比如那個賦值中的'mmap'系統調用。 – karlicoss

+0

@ karlicoss:我不確定我明白你爲什麼不能使用'new'運算符;特別是我不確定我是否理解這部分:「*我必須編寫內存分配器,其他程序(二進制文件,如gcc或vim或其他)將使用*」。但是,我不需要了解,只要你知道你在做什麼;)無論如何,這個故事的道理是:你不能從它聲明的命名空間中取出一個實體,但是你應該*希望你的實現將在'std'命名空間中聲明它們。如果不是這樣的話,至少你做了你的部分,包括正確的標題。 –

+0

,因爲'new'和'delete'仍然是這個家庭任務的高級內存抽象。那麼,我必須實現一個內存管理庫(使用'malloc','free','calloc'等),基本上我必須實現[heap](http://en.wikipedia.org/wiki/)堆_(編程))我自己。然後,我將運行'LD_PRELOAD = myallocator.so some_program'之類的東西,該程序將使用我的內存分配器,而不是'g ++'提供的內存分配器。 – karlicoss

相關問題