C ++详细命名空间vs匿名vs私有方法到class与pimpl和朋友类

时间:2017-07-13 22:19:08

标签: c++ namespaces friend-class

在这里忍受我。 我试图找出你在什么时候绘制关于将辅助方法放在anon与详细命名空间与私有与创建pimpl或朋友类之间的界限。

这是我的看法..请让我知道你的想法。

所以,如果我有   foo.hpp   Foo.cpp中

我有一些自由函数bar,它们不访问foo中的任何数据成员,而且没有客户端需要知道这些自由函数,只有foo.cpp的方法需要它们只需将它们直接放在foo.cpp中的anon命名空间中即可完成。

但是,如果bar需要访问foo的数据成员,我们可以使用bar foo的私有方法。但这意味着即使foo的客户端并不真正关心bar,每次bar更改时,我们都会重新编译。

(这部分我有点模糊): 但是,在这种情况下至少使用详细命名空间可以帮助foo.hpp的读者不要费心查看bar,因为他们真的不需要知道它。这是详细命名空间约定的一般用法吗?

现在,如果我们有一堆bar_1,bar_2 ... bar_n并且它们有关联,他们需要访问数据成员,我可以将朋友类baz设为foo,并放置{{ 1}}那里。

但是,如果我真的很关心编译时间和隐藏界面我可以诉诸pimpl(在这部分再次非常模糊,通常如果我看到这个,闹铃响了,告诉我设计中有些东西掉了)

你的想法......

1 个答案:

答案 0 :(得分:3)

正如前面有人评论过的那样,最好提供一个带有问题的代码示例,因为您描述的概念非常抽象和复杂。

以下是我想了解更多信息的项目:私有方法,私有实现,未命名的命名空间非成员函数,“命名”命名空间中的非成员函数和朋友非成员函数。

隐私方法:首先,您必须在类声明中声明这些内容,以便即使您班级以外的任何人都无法调用它们,原型也将公开显示。这有点不合情理。你应该在两种情况下使用这些方法:

  1. 在执行此方法时,您需要访问类中的私有内容。
  2. 您正在使用NVI惯用法实现虚拟方法。
  3. 私有化实施:您应该使用它来隐藏类的实现细节。 AKA的数据成员。我经常做的一件事是在我的类头文件中转发声明我的pImpl类型,并在cpp文件中创建私有实现类的类朋友。

    未命名的命名空间非成员函数:这些或多或少等同于在实现文件中使用static关键字声明的非成员函数。你应该尽可能地为那些人射击。一个好的经验法则是,所有非虚拟私有方法都应该可以作为非友好的非成员函数实现,而不是未命名的命名空间。这样做的好处是它会强制您在实现此类函数时使用类的公共接口。一个重要警告:永远不要在头文件中使用未命名的命名空间。 (.h或.hpp)如果这样做,那么每次包含该文件时,这些文件中的每个原型都将具有唯一的符号。这可能会导致符号混乱。

    命名空间中的非成员非友元函数:大多数情况下,当您想要向类添加服务或提供未绑定到类的辅助函数时,您将使用这些函数类。这些函数的优点是它们只使用类的公共接口。很好地使用这些方法的一个很好的例子就是为您的类实现运算符。 假设你有“A”级和“B”级。并且您希望将A的实例添加到B的实例。传递规则表明您还可以将B添加到A并获得相同的结果。如果您使operator + non成员,则不必修改任何类来实现此功能。如果您将其作为公共方法执行,则必须在两个类中执行此操作。如果你想了解更多有关该主题的信息,我会向你推荐Scott Meyers“Effective C ++”。

    朋友非会员功能:您应尽可能避免使用这些功能。原因是他们的实现依赖于您班级的私人细节。为什么你会让他们成为朋友?可以接受的是,类的私有实现细节可以随时改变,这可能会破坏您的功能或更糟:使其行为方式与预期不同。

    所以你有它,当你有虚拟方法通过NVI惯用法声明时,使用私有方法,将你的数据成员放在私有实现中,在你的实现文件中声明所有非虚拟私有方法在未命名的命名空间下,尽可能将公共服务声明为非成员非朋友函数,不要使用任何朋友非成员函数。