2012-05-30 65 views
54

考慮一對兩個源文件:一個接口聲明文件(*.h*.hpp)及其實現文件(*.cpp)。C++:名稱空間 - 如何在頭文件和源文件中正確使用?

*.h文件是這樣的:

namespace MyNamespace { 
    class MyClass { 
    public: 
    int foo(); 
    }; 
} 

我已經看到了兩種不同的做法,在源文件中使用的命名空間:

*.cpp顯示實踐#1:

#include "MyClass.h" 
using namespace MyNamespace; 

int MyClass::foo() { ... } 

*.cpp顯示練習#2:

#include "MyClass.h" 
namespace MyNamespace { 

    int MyClass::foo() { ... } 

} 

我的問題:這兩種做法是否有區別,是否認爲比其他更好?

+23

還有選項3 :只是我們的全名,例如'int MyNamespace :: MyClass :: foo()...'。 –

+1

可能的重複:http://stackoverflow.com/questions/7789163/using-directive-best-practice – David

+0

@Dave不重複。這些問題相互補充。建議將Dave提供的鏈接添加爲「另請閱讀...」以解決此問題。我的問題將幫助新手選擇正確的風格。 – DaddyM

回答

42

從代碼的可讀性的角度來看,它可能是在我使用#2方法爲此觀點更好:

你可以在同一時間using多個命名空間,任何物體或函數編寫的線下可以屬於任何這些名稱空間(禁止命名衝突)。在namespace塊包裹整個文件更加明確,並允許你聲明屬於該命名空間中的.cpp文件中,以及

+0

謝謝。非常清楚。會稍等一會再提供答案。 – DaddyM

+0

Dave在他對你的問題的評論中提到的問題也概括了你正在查看的兩種方法之間的差異(如果有的話)中的一些關鍵點 –

+0

夥計們,我真的不知道誰選擇的答案。他們有交集,而相互補充。 – DaddyM

36

最明顯的是選項,您沒有表現出新的函數和變量:

int MyNamespace::MyClass::foo() 
{ 
    // ... 
} 

它也非常冗長;對大多數人來說太多了。由於using namespace是名稱衝突的代名詞,至少在我的經驗中, 並且應該避免,除非在非常有限的範圍和地點中,我通常使用# 。

+2

非常感謝。我們一起爲名稱空間用戶提供了一個很好的FAQ頁面。 :) – DaddyM

+0

夥計們,我真的不知道誰選擇的答案。他們有交集,而相互補充。 – DaddyM

4

是這兩種做法

是它們之間的任何差別。 #1和#2分別是using-directivenamespace definition的示例。在這種情況下,它們實際上是相同的,但會產生其他後果。舉例來說,如果你介紹一起MyClass::foo一個新的標識,這將有不同的適用範圍:

#1:

using namespace MyNamespace; 
int x; // defines ::x 

#2:

namespace MyNamespace { 
    int x; // defines MyNamespace::x 
} 

是一個被認爲優於另一個?

#1優點:多一點簡潔;更難以無意中將某物引入MyNamespace。缺點:可能無意中拉入現有標識符。

#2優點:更清楚的是現有標識符的定義和新標識符的聲明都屬於MyNamespace。缺點:更容易無意中將標識符引入MyNamespace

對#1和#2的批評是,當你可能只關心MyNamespace::MyClass成員的定義時,他們指的是整個命名空間。這是嚴厲的,它傳達的意圖不佳。

一個可能的替代#1是一個using-declaration只包括您感興趣的標識符:

#include "MyClass.h" 
using MyNamespace::MyClass; 

int MyClass::foo() { ... } 
2

我想還補充說,如果你決定,由於某種原因,以實現模板專業化的CPP文件,只是依靠using namespace你會遇到以下問題:

// .h file 
namespace someNameSpace 
{ 
    template<typename T> 
    class Demo 
    { 
     void foo(); 
    }; 
} 

// .cpp file 
using namespace someNameSpace; 

template<typename T> 
void Demo<T>::foo(){} 

// this will produce 
// error: specialization of 'template<class T> void someNameSpace::Demo<T>::foo()' in different namespace [-fpermissive] 
template<> 
void Demo<int>::foo(){} 

否則,如果你申請#2的方法,這將是罰款。

0

我想補充一個方式,使用使用聲明

#include "MyClass.h" 
using MyNamespace::MyClass; 

int MyClass::foo() { ... } 

這樣打字命名空間的名稱很多時間可以節省你,如果類有很多功能

相關問題