2014-03-05 137 views
1

我一直在尋找頭文件中使用使用聲明的一些說明(我在四處搜索,但無法完全得到我正在尋找的答案)。我的研究結論迄今爲止,在非全局範圍內使用它們是可以的,而命名空間指令是不好的。我明白(至少我希望如此:))。在頭文件中使用聲明

所以在我的例子中我使用了shared_ptr s,但我需要支持在std::命名空間中沒有它們的舊編譯器,例如std::tr1::。由於每個使用shared_ptr的類都需要相同的shared_ptr定義,因此我必須在每個這些頭文件中放入正確的#include指令並使用聲明。所以我將這部分移到了一個單獨的頭文件中,所以我只有一個文件需要進行更改。關於使用哪個shared_ptr的決定是通過預處理器指令HAS_SHAREDPOINTER進行的,如果用戶具有支持std::shared_ptr的編譯器,則該設置被設置。

SharedPtr.h

#ifndef SHAREDPTR_H_ 
#define SHAREDPTR_H_ 

#ifdef HAS_SHAREDPOINTER 
#include <memory> 
using std::shared_ptr; 
#else 
#include <tr1/memory> 
using std::tr1::shared_ptr; 
#endif 

#endif /* SHAREDPTR_H_ */ 

現在在使用shared_ptr的每一個頭文件,包括我這個頭文件。例如,在

ModelPar.h

#ifndef MODELPAR_H_ 
#define MODELPAR_H_ 

#include <string> 
#include <set> 

#include "SharedPtr.h" 

class ModelPar { 
    private: 
    std::set<shared_ptr<ModelPar> > connections; 
    ... 
}; 

#endif /* MODELPAR_H_ */ 

現在我認爲我所做的是錯的,因爲這包含任何我的頭文件(使用shared_ptr S)用戶的方式也有相應的在他的代碼中使用聲明。這是壞事,因爲用戶沒有意識到這一點......所以我把我的使用聲明放在全局範圍內。要麼?我有點困惑和困惑如何正確地做到這一點?提前致謝!

回答

0

好的,我自己找到了「答案」。我想我沒有意識到命名空間中的using聲明在名稱空間相同的名稱空間下仍然有效。現在Bjarne的話也更有意義,人們不應該污染全球命名空間:)。如果我仍然做錯了,請糾正我。

SharedPtr.h:

#ifndef SHAREDPTR_H_ 
#define SHAREDPTR_H_ 

#ifdef HAS_SHAREDPOINTER 
#include <memory> 
namespace blub { 
using std::shared_ptr; 
} 
#else 
#include <tr1/memory> 
namespace blub { 
using std::tr1::shared_ptr; 
} 
#endif 

#endif /* SHAREDPTR_H_ */ 

ModelPar.h:

#ifndef MODELPAR_H_ 
#define MODELPAR_H_ 

#include <string> 
#include <set> 

#include "SharedPtr.h" 

namespace blub { 

    class ModelPar { 
    private: 
    std::set<shared_ptr<ModelPar> > connections; 
    ... 
    }; 
} 

#endif /* MODELPAR_H_ */ 
+0

也許是文體偏好的問題,但是......定義在namespace blub中使用條件'shared_ptr'的所有內容是沒有必要的,也不太直觀。並且認爲在'struct's中聲明類型別名是有利的(例如,用於模板),無法爲定義重新打開它作爲類型名稱的快捷方式。所以,據我所知,更習慣的方法是使用包含它的'namespace'或'class'來限定別名的所有用法:'struct MyTypes {using shared_ptr = std :: shared_ptr; }; /*...*/ std :: set >' –

0

我本人沒有看到有任何頭 '使用' 任何好處。 永恆

這不僅使得它非常難以重新設置因爲編譯器錯誤將變得毫無用處,如果您刪除標題頭包含鏈。獲取錯過聲明300多錯誤,未定義類型等;並不完全是我對'有趣時間'的定義。

當然,您可以使用一些預處理器魔術來完成它,而不管名稱衝突。但爲什麼?如果你的命名空間有碰撞,那麼你的方法就會出現問題,這樣繞過火災報警器並聲稱不再有火災。

作爲額外的好處,它也掩蓋了班級的祖先「我是從X命名空間使用FooClass還是從Y?」。

+0

嗨Manuel,嗯,我明白你的意思,並且認爲把它放在頭文件中是沒有意義的,但只是在源文件中文件。通常這就是我所做的,但是我怎麼能解決這個問題呢?不幸的是,我不能要求C++ 11的項目,所以我必須適應...... – steve

+0

在你的頭文件中,你需要使用你正在使用的類的完整聲明。像'std :: set >連接;'。 看起來像你想要的是一個位置來管理你正在使用的實現;因爲你可以用一個包裝器來包裝共享指針,所以使用它看起來像'std :: set >連接;' – Manuel

相關問題