6

当我使用 pimpl 习惯用法时,将所有方法定义放在类定义中是个好主意吗?例如:

// in A.h

class A {
   class impl;
   boost::scoped_ptr<impl> pimpl;
public:
   A();
   int foo();
}

// in A.cpp

class A::impl {
   // method defined in class
   int foo() {
       return 42;
   }

   // as opposed to only declaring the method, and defining elsewhere:
   float bar();
};

A::A() : pimpl(new impl) { }
int A::foo() {
   return pimpl->foo();
}

据我所知,将方法定义放在类定义中的唯一问题是(1)实现在包含类定义的文件中可见,以及(2)编译器可能使方法内联。

在这种情况下,这些都不是问题,因为类是在私有文件中定义的,并且内联没有效果,因为方法只在一个地方被调用。

将定义放在类中的好处是您不必重复方法签名。

那么,这样可以吗?还有其他需要注意的问题吗?

4

4 回答 4

3

我认为您回答了自己的问题:两种解决方案都是等效的。

但是,我不太确定“内联没有效果,因为这些方法只在一个地方被调用”:当函数没有被内联时,可能会存在一个额外的调用。但很有可能编译器足够聪明,可以将它们优化为远离外部类中的单行转发调用。

最后,我相信这只是一个品味问题。

于 2010-12-23T09:37:34.317 回答
2

好处:

  • 该类的所有代码都已本地化

缺点:

  • 对于较大的类:当需要滚动时,要知道函数属于哪个类变得更加困难。
  • 当函数驻留在所有类声明之后时,依赖关系更容易解决。否则,当内部类相互依赖时,可能需要将某些类声明移到其他类声明之后,而某些函数仍必须移到类声明之后。
于 2010-12-23T10:28:37.610 回答
1

通常我不会将方法添加到 Impl 内部类,但如果您内联定义方法,我看不到任何问题。在我看来,这比单独的声明和定义更具可读性。

于 2010-12-23T09:39:15.900 回答
0

编译器是否内联方法取决于编译器和传递的参数。

在 pimpl 习惯用法的情况下,我认为方法是否在 Imp 的体内定义并不重要。我个人喜欢在外面定义它们,因为很容易看出什么是真正重要的(比如成员变量和方法列表)。

于 2010-12-23T09:49:47.447 回答