C++ 我应该在哪里实施这一点;“私人”;辅助函数?

C++ 我应该在哪里实施这一点;“私人”;辅助函数?,c++,C++,我的类定义分布在头文件和源文件中: // T.hpp class T { public: void foo(); }; // T.cpp void T::foo() { } 如果T::foo需要使用一些只对T可见的辅助函数,下面哪种解决方案是最好的 1.私人会员 2.自由函数只能在类定义的TU中访问 除了前者之外,还有什么区别吗?头文件中的函数更多?更喜欢自由的非友元函数而不是成员函数,因为它们对类成员的访问权限比成员函数少,因此引入错误的机会也更少 如果函数完全不在

我的类定义分布在头文件和源文件中:

// T.hpp

class T {
   public:
      void foo();
};

// T.cpp

void T::foo() {

}
如果
T::foo
需要使用一些只对
T
可见的辅助函数,下面哪种解决方案是最好的

1.私人会员 2.自由函数只能在类定义的TU中访问
除了前者之外,还有什么区别吗?头文件中的函数更多?

更喜欢自由的非友元函数而不是成员函数,因为它们对类成员的访问权限比成员函数少,因此引入错误的机会也更少

如果函数完全不在接口范围内,则还应将其放在实现文件中的未命名命名空间中。这将进一步减少出现bug的机会,因为其他翻译单元将无法调用该函数


在未命名名称空间中使用非友人的另一个优势是,更改头的可能性较小(因为其中的实体较少)。由于编译时依赖关系,更改头文件通常会大大降低构建时间。不管是不是私有的,你可能会有很多翻译单元,这取决于标题中所有内容的编译。

据我所知,你已经基本掌握了。除了头文件将不必要地增长之外,没有其他区别。不过,您也可能在类的API中泄漏了一些实现细节。

需要访问私有成员的自由函数无论如何都需要在头中声明友元,因此它们可能并不比私有成员函数好

不需要私有访问的函数应该是自由函数,无论它们是否在头中声明

因此,如果他们需要访问私人成员,那么就让他们成为成员。否则,使它们成为自由函数

Scott Meyers有一个算法,用于确定与类C相关的函数f应该是成员、友元非成员还是非成员非友元:

if(f需要是虚拟的)
使f成为C的成员函数;
如果(f是运算符>>或

操作员是的,存在差异

如果函数不是类的一部分,那么最好不要将它们绑定到此特定类:

  • 您可能希望在另一个类中使用它们,在这种情况下,将它们移动到某个共享位置并在两个类中使用将非常容易

  • 如果函数(可能是自由函数)将第三方类作为参数,并且如果将其作为成员函数,则必须包含另一个.h文件(具有此类定义)或在.h文件中声明此类。这意味着更多耦合,这是不好的:)


因此,我更愿意将它们作为自由类编写(可能在未命名名称空间的.cpp文件中,如果它们没有(也可能不会)在其他类中使用的话)

这使得nosenseatal成为可能。使用成员函数还是自由函数与是在头文件还是在源文件中定义它们无关。我想我理解。如果我的编辑无效,请告诉我。请参阅。@Benj:不,如果free函数仅对该源文件可见并在其中使用,则它们不会。欢迎您在源文件顶部声明这些“本地”函数。与将它们添加到类的公共API正交。@nosenseal:很好。我认为这个版本比难以解析的散文要清晰得多。如果我的类是一个模板类,因此在头文件中实现,我该怎么办?我需要在模板类的头中使用“private-free函数”来调用它,但这样它就不再是私有的了。
// T.hpp

class T {
   public:
      void foo();
   private:
      void helper();
};

// T.cpp

void T::foo() {
    helper();
}

void T::helper() {
}
// T.hpp

class T {
   public:
      void foo();
};

// T.cpp

namespace {
    void helper() {}
}

void T::foo() {
    helper();
}
if (f needs to be virtual)
   make f a member function of C;
else if (f is operator>> or
         operator<<)
   {
   make f a non-member function;
   if (f needs access to non-public
       members of C)
      make f a friend of C;
   }
else if (f needs type conversions
         on its left-most argument)
   {
   make f a non-member function;
   if (f needs access to non-public
       members of C)
      make f a friend of C;
   }
else if (f can be implemented via C's
         public interface)
   make f a non-member function;
else
   make f a member function of C;