1

在这里忍受我。我试图弄清楚你在什么时候画出关于将辅助方法放入 anon、detail 命名空间、私有和创建 pimpl 或朋友类的界限。

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

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

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

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

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

现在,如果我们有一堆 bar_1、bar_2...bar_n 并且它们相互关联并且它们需要访问数据成员,我可以baz为 foo 创建一个朋友类,并将bars 放在那里。

但是,如果我真的很担心编译时间和隐藏界面,我可以求助于 pimpl(这部分再次非常模糊,通常如果我看到这个,警报会响起并告诉我设计中有问题)。

你的意见...

4

1 回答 1

5

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

以下是我对您想进一步了解的项目的看法:私有方法、私有实现、未命名命名空间非成员函数、“命名”命名空间中的非成员函数和友元非成员函数。

私有方法:首先你必须在你的类声明中声明它们,这样即使你的类之外没有人可以调用它,它们的原型也将是公开可见的。这有点不合情理。您应该在两种情况下使用这些方法:

  1. 在此方法的实现中,您需要访问您的类私有的东西。
  2. 您正在使用 NVI 习惯用法实现虚拟方法。

私有实现:你应该使用它来隐藏你的类的实现细节。又名它的数据成员。我经常做的一件事是在我的类头文件中转发声明我的 pImpl 类型,并使我的类成为 cpp 文件中私有实现类的朋友。

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

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

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

所以你有了它,当你有通过 NVI 习惯用法声明的虚拟方法时使用私有方法,将你的数据成员放在私有实现中,在未命名命名空间下的实现文件中声明所有非虚拟私有方法,声明公共服务as non-member non-friend functions 尽量不要使用任何friend non-member 函数。

于 2017-07-14T00:25:40.683 回答