C++ 对于重复的代码,哪一个是最好的?
我有一个类,它有两个成员函数,它们共享一段代码:C++ 对于重复的代码,哪一个是最好的?,c++,C++,我有一个类,它有两个成员函数,它们共享一段代码: void A::First() { firstFunctionEpilogue(); sharedPart(); } void A::Second() { secondFunctionEpilogue(); sharedPart(); } 当前,firstFunctionEpilogue()、secondFunctionEpilogue()和sharedPart()都不是函数调用,只是代码片段,sharedPart()
void A::First()
{
firstFunctionEpilogue();
sharedPart();
}
void A::Second()
{
secondFunctionEpilogue();
sharedPart();
}
当前,firstFunctionEpilogue()
、secondFunctionEpilogue()
和sharedPart()
都不是函数调用,只是代码片段,sharedPart()
代码被复制。我想消除重复
共享代码不需要访问类的任何成员。因此,我可以将其作为以下三项之一实施:
- 一个静态成员函数
- 常量非静态成员函数或
- 局部函数
哪种变体更好?为什么?如果您的函数访问状态但不更改状态,则使用常量成员函数 您的案例: 如果您的函数1)不需要访问代码的任何成员,2)与该类相关,则将其作为类的静态函数 这样很明显,它既不是在修改状态,也不是基于对象的状态 您没有提及的额外案例:
还有一件事你也可以做。这就是让SharedPart接受一个成员函数指针,调用它,然后处理它的主体。如果你有很多第一个(),第二个(),第三个(),第四个()。。。这样的函数可以减少代码重复。这样,您就不需要一直调用SharedPart();在每个成员函数的末尾,您可以重用First()、Second()、THird()、。。。不调用代码的SharedPart() 或者它可能在另一个类中 或者,如果它是一个成员,它可以是虚拟的 有很多决定,我不会太强调。通常,我选择const非静态成员函数作为默认值,除非我有充分的理由不这样做
- 这可能无关紧要,所以与其说是“最佳实践”,不如说是“不要做任何疯狂的事情”
- 如果类及其所有成员都是在其头中定义的,那么私有静态成员函数可能是最好的,因为它清楚地表明“不适用于客户端”。但对于非成员函数,有一些方法可以做到这一点:不要记录它,在注释中加上“不适用于客户端”,然后将整个内容粘贴在
名称空间中,小心豹子的名称空间中
- 如果类成员函数是在.cpp文件中定义的,那么像这样的小助手函数最好作为.cpp文件中的自由函数。静态名称空间或匿名名称空间
即使它是一个简单的算术表达式,将其作为特定用途类的某些算术的成员(静态或非静态)也可能有用。将其作为非成员函数。 共享代码不需要访问类的任何成员 作为一般规则,如果一段代码不需要访问类的任何成员,请不要将其作为成员函数!尽可能多地封装类 我建议在单独的名称空间中执行一个非成员函数,该函数将调用公共方法,然后调用为共享代码创建的函数 以下是我的意思的一个例子:
namepsace Astuff{
class A{...};
void sharedPart(){...};
void first(const A& a);
void second(const A& a);
}
void Astuff::first(const A& a){
a.first();
sharedPart();
}
使其成为非成员非好友函数。Scott Meyer对此有很好的解释(也有有效的C++第三版的第23条)。
作为经验法则“尽量保持它的局部性,但必要时可以看到”。 如果调用函数的所有代码都驻留在同一个实现文件中,这意味着将其保留在实现文件的本地
如果将其作为类的私有静态方法,则包括类在内的实现将无法调用它,但它们仍然可以看到它。因此,每次更改该方法的语义时,包括调用在内的所有实现都必须重新编译——这是一个相当大的负担,因为从他们的角度来看,他们甚至不需要知道这些语义 因此,为了最大限度地减少不必要的依赖关系,您需要将其设置为静态全局函数 但是,如果您发现自己在多个实现文件中重复此全局函数,则应该将该函数移动到单独的头文件/实现文件对中,以便所有调用方都可以包含它 无论您是将该函数放置在名称空间中、全局范围内,还是将其作为类中的静态函数,都完全取决于您的喜好 最后,如果您要使用全局静态函数,那么会有一个“更多C++”的版本:匿名命名空间。它有一个很好的特性,它可以实际存储状态,还可以防止用户甚至可以向前声明它的任何函数// in your .cpp file
namespace /*anonymous*/
{
void foo()
{
// your code here
}
};
void MyClass::FooUser1() { foo(); }
void MyClass::FooUser2() { foo(); }
我更喜欢将其设置为非成员函数(可能隐藏在子名称空间中,以清楚地表明它不应该是成员函数)