2012-02-06 32 views
5

我已經在外部* .cpp文件中定義了一些函數(這裏沒有涉及類),當然還有一個合適的* .h文件。收到我在實現文件中使用未命名的名稱空間?

* .cpp文件中的某些功能僅在中使用,在* .cpp文件中無處可用。他們甚至沒有在* .h文件中提及。

我應該將這些函數放到一個未命名的命名空間中嗎?或者他們可能住在旁邊的其他函數?如果是這樣,爲什麼我需要一個未命名的名稱空間給他們?我看不出問題,因爲無論如何這些功能都無法從外部訪問。

+0

爲什麼不讓它們變成靜態的? (如在一個靜態的C函數,而不是一個靜態類方法) – 2012-02-06 17:41:40

+1

@JamesMcLaughlin:在C + + 03「靜態」已被棄用,爲此目的。但是,C++ 11並不反對它。但是'靜態'並且處於未命名的名稱空間中意味着不同的事情。 'static'會給它內部的連接,所以這個函數不能用於某些目的。 – 2012-02-06 17:45:18

+0

感謝您的建議。 這些解決方案是靜態的還是無名的命名空間,推薦或首選? – user1192880 2012-02-06 17:49:02

回答

9

如果您希望它們對該編譯單元真正是私有的,請將它們置於匿名命名空間中。如果你不這樣做,那麼有人可以在別處聲明這些功能並明確地使用它們。

看看下面的例子:

// library.cpp 

// a "private" function here, in that it is not declared anywhere 
void f() {} 

namespace 
{ 
    // same as above, except within an anonymous namespace 
    void g() {} 
} 

// client.cpp 

void f(); 

int main() 
{ 
    // Can call f(), it's been declared and is now effectively "public" 
    f(); 

    // compilation error, this has no idea what g() is, it's not declared 
    // in any scope that can be resolved here 
    g(); 

    return 0; 
} 
+0

謝謝!我不知道那個「功能」。 – user1192880 2012-02-06 17:50:06

+0

這就是'static'的用途。匿名命名空間爲類和結構體提供了此功能。 – 2012-02-06 18:01:01

+0

'static'關鍵字是否也可以防止與代碼其他部分中可能存在的其他函數發生名稱衝突?未命名的命名空間將會。 – Chad 2012-02-06 19:09:32

1

我想如果你不想被從外面看到這些函數聲明爲static

+0

*「...從外面看......」 - - 從什麼外面?標題?翻譯單位? – jww 2017-09-29 07:15:26

4

你的問題可以被一分爲二:

1「?如何隱藏全局函數」

一個簡單的方法來做到這一點,是把函數的頭到頭文件:

//============================ 
// Filename: "mylibrary.hpp" 
//============================ 
// Description: 
// Utility functions. 
//============================ 
#ifndef MYLIBRARY_H_INCLUDED 
#define MYLIBRARY_H_INCLUDED 
//============================ 

namespace MyLibrary 
{ 
    void DoSomething(); 
} // namespace MyLibrary 

//============================ 
#endif // MYLIBRARY_H_INCLUDED 
//============================ 

全部代碼文件:

//============================ 
// Filename: "mylibrary.cpp" 
//============================ 
// Description: 
// Utility functions. 
//============================ 
// self header include 
#include "mylibrary.hpp" 
//============================ 

namespace MyLibrary 
{ 
    void DoSomethingBefore() 
    { 
     // ... 
    } 

    void DoSomethingAfter() 
    { 
     // ... 
    } 

    void DoSomethingConfirmed() 
    { 
     // ... 
    } 

    void DoSomething() 
    { 
     DoSomethingBefore(); 
     DoSomethingConfirmed(); 
     DoSomethingAfter(); 
    } 
} // namespace MyLibrary 

//============================ 
#endif // MYLIBRARY_H_INCLUDED 
//============================ 

當這編譯,你會得到一個「mylibrary.o」或「mylibrary.obj」文件。您可以將其提供給其他開發人員:「mylibrary.hpp」加上「mylibrary.obj」,但不帶「mylibrary.cpp」文件。大多數「普通c」/「C++」編譯器都可以這樣工作。

還有其他的方法,請閱讀下一節。

2.「匿名命名空間是隱藏全局函數的好技術嗎?」

「匿名命名空間」技術是隱藏全局函數的另一種方法。

有一個類似的問題:

Unnamed/anonymous namespaces vs. static functions

但是,我個人不推薦這種技術,被譽爲「最喜歡」的答案。

命名空間是其中之一,我希望自「純c」或「C++」開始就存在。但是,「匿名命名空間」或「無名命名空間」似乎很奇怪。

它就像試圖隱藏一些東西,然後忘記,你在哪裏存儲它。

3項其他建議

(一)我建議使用單一主REQUIRED,每個文件不可選,非匿名的命名空間。它可能具有嵌套的附加內部命名空間。每個主名稱空間應該具有相同的ID。作爲文件名,但沒有文件擴展名或文件後綴。 (b)避免匿名命名空間。它像存儲倉庫中的東西,沒有索引。 (c)在頭文件中使用文件擴展名或文件前綴,可能是「.h」或「.hpp」,即使它是一個C++文件也是如此。該標準規定C++不應在「C++」文件上使用文件擴展名或文件後綴,但很難在文件系統上識別或查找。

祝你好運。

相關問題