【问题标题】:typedef boost::shared_ptr<MyJob> Ptr; or #define Ptr boost::shared_ptrtypedef boost::shared_ptr<MyJob> Ptr;或#define Ptr boost::shared_ptr
【发布时间】:2011-03-04 09:59:55
【问题描述】:

我刚刚开始研究一个新的代码库,其中每个类都包含一个 shared_ptr typedef (similar to this),例如:

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 定义保存在每个类中。

【问题讨论】:

  • 一般情况下,除非绝对必要,否则应避免使用宏,并在确实需要它们时谨慎命名。 C++ 名称可以包含在类、函数或命名空间范围内,并且在不同上下文中使用相同名称时不会导致冲突。宏名称会在每个范围内呕吐,并且可以以完全意想不到的方式无形地更改代码。
  • 当我看到 boost::shared_ptr 我确切地知道它的作用。如果我在代码中看到 Ptr,我必须查找它的含义,并且在不同的模块中存在具有不同含义的潜力(因为您的同事可能在他的代码中对它的定义不同)。保持代码清晰并使用全名。

标签: c++ boost naming-conventions shared-ptr


【解决方案1】:

宏 (#define) 始终是全局定义的。 这意味着每次使用“字符串”Ptr(甚至是变量)都将被宏替换。

typedef 可以放在一个类中,在一个命名空间中,......所以你可以更好地控制它。

编辑: 另一个优点是您可以在不同的类中拥有不同的 Ptr 类型,例如

  • ClassX::Ptr 是一个 boost shared_ptr
  • ClassY::Ptr 可以是另一个 shared_ptr
  • ClassZ::Ptr 可以是简单的“Class Z *”指针

如果这些类随后在模板化代码中使用,您可以使用 T::Ptr 作为类的指针类型,模板将使用最适合该类的指针。

【讨论】:

  • 让类为 Ptr 定义自己的含义对我来说似乎很危险。例如ClassZ::Ptr 需要被显式删除,而其他不需要,客户端代码如何知道这一点?
  • 也许“Class Z *”指针案例是一个不好的例子,但该参数对于其他类型的智能指针仍然有效。我想举一个例子,是类本身决定了指向它的最佳方式,而不是类的用户。
  • 这不是一个坏例子。您正在复制一个指针,因此只有一个副本的持有者必须执行delete。传统上是拥有资源的人。可以将副本传递给其他人而不让他们担心,当然,您最好确保对象在他们打算使用它时仍然存在。
【解决方案2】:

定义的缺点已在网络上广泛讨论。例如,它将与另一个命名空间中的 Ptr 发生冲突:

someLibrary::Ptr somethingElse -&gt; somelibrary::crap

如果输入 boost::shared_ptr 真的很烦人,你可以是using namespace boost。它将保持可读性(人们真的很想知道它是 boost shared_ptr)。

我可以建议您的另一件事是一系列 typedef。在我的公司,约定 MyClassPtr 是 boost::shared_ptr 的 typedef。

【讨论】:

  • 我应该让我的问题更清楚地说明#define 的问题(现在已经对其进行了编辑)。我同意你的观点,使用命名空间提升似乎比节省打字更可取,我想知道为什么通常使用 typedef Ptr 习语。
【解决方案3】:

是节省打字的唯一目的 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 2011-09-27
    • 2013-06-12
    • 2013-04-16
    相关资源
    最近更新 更多