2010-06-16 100 views
2

我剛開始在一個新的代碼庫,每個類包含一個shared_ptr的typedef(similar to this)一樣工作:typedef boost :: shared_ptr <MyJob> Ptr;或者將#define PTR的boost :: shared_ptr的

typedef boost::shared_ptr<MyClass> Ptr; 

是節省打字的boost :: shared_ptr的唯一目的?

如果是這樣的話,是唯一的理由不這樣做

#define Ptr boost::shared_ptr 

在一個共同的標頭的#define的普遍問題?然後,你可以這樣做:

Ptr<MyClass> myClass(new MyClass); 

這是不超過

MyClass::Ptr myClass(new MyClass); 

更多的輸入並保存在每類中的PTR定義。

+3

一般而言,除非絕對必要,否則應避免使用宏,並在需要時非常小心地命名它們。 C++名稱可以包含在類,函數或命名空間範圍內,並且當在不同的上下文中使用相同的名稱時不會導致衝突。宏名稱嘔吐在每個範圍內,並且可以以完全意想不到的方式無形地更改代碼。 – 2010-06-16 12:25:55

+2

當我看到boost :: shared_ptr時,我確切地知道它的作用。如果我在代碼中看到Ptr,我必須查看它的含義,並且可能在不同模塊中具有不同含義(因爲您的代碼中您的共同工作可能會有不同的定義)。保持代碼清晰並使用全名。 – 2010-06-16 18:12:32

回答

9

宏(#define)總是全局定義的。 這意味着'串'Ptr(即使是一個變量)的每一次使用都將被宏所取代。

typedef可以放在一個類中,在一個名稱空間中......所以你可以更好地控制它。

編輯: 另一個優點是,你可以在不同的類,例如,

  • ClassX :: PTR是升壓shared_ptr的
  • 優雅:: PTR可以是另一個shared_ptr的
  • ClassZ :: PTR可以是簡單的 「類Z *」 指針

如果這些然後在模板化代碼中使用類,可以使用T :: Ptr作爲類的指針類型,並且該模板將使用該類最合適的指針。

+1

讓班級爲Ptr定義自己的含義對我來說似乎很危險。例如ClassZ :: Ptr需要被顯式刪除,而其他的則不需要,客戶端代碼如何知道這一點? – danio 2010-06-16 11:07:36

+0

也許「Class Z *」指針情況是一個不好的例子,但該參數對其他類型的智能指針仍然有效。我想舉一個例子,它是類本身,它決定了指向它的最佳方式,而不是該類的用戶。 – Patrick 2010-06-16 11:19:55

+0

這不是一個壞例子。您正在複製一個指針,因此只有一個副本的持有者必須執行「刪除」。傳統上是擁有資源的那個。將副本傳遞給其他人並不會讓他們擔心,儘管當然你最好確定只要他們打算使用它,對象就會活着。 – 2010-06-16 11:28:45

2

定義的缺點已經在網絡上廣泛討論過了。例如,它會在另一個命名空間PTR碰撞:

someLibrary::Ptr somethingElse -> somelibrary::crap

如果鍵入的boost :: shared_ptr的真正惹惱了,你可以using namespace boost。它會保持可讀性(人們真的想知道它的提升shared_ptr)。

我建議你的另一件事是一系列typedefs。在我的公司裏,有一個約定,MyClassPtr是一個用於boost :: shared_ptr的typedef。

+0

我應該讓我的問題更清楚一些關於#define的問題(現在已經編輯它來做到這一點)。 我同意你的看法,使用命名空間增強似乎是更好的保存類型,我想知道爲什麼typedef Ptr習慣用法是常用的。 – danio 2010-06-16 11:10:13

2

是保存打字的唯一目的 boost :: shared_ptr?

是的,非常多。那麼,不是爲了節省本身打字,這是爲了提高的可讀性。但我認爲這就是你的意思。

比較這些,看看你喜歡。沒有正確的答案,除了要意識到宏和命名空間混亂的問題。

boost::shared_ptr<Foo> func (boost::shared_ptr<Foo> a, boost::shared_ptr<Foo> b); 

shared_ptr<Foo> func (shared_ptr<Foo> a, shared_ptr<Foo> b); 

Ptr<Foo> func (Ptr<Foo> a, Ptr<Foo> b); 

Foo::ptr func (Foo::ptr a, Foo::ptr b); 

FooPtr func (FooPtr a, FooPtr b); 

Foo* func (Foo* a, Foo* b); 
相關問題