2010-06-16 102 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); 
相关问题