我发现很难决定什么时候使用私有静态成员函数,什么时候使用私有const成员函数。
假设我们有一个方法DoSomething(),它需要检查一个或多个成员是否为某事:
class Foo
{
public:
void DoSomething()
{
// if(IsASomething()) ...
// or
// if(IsSomething(a_)) ...
private:
int* a_;
int* b_;
static bool IsSomething(int* n) {return n != null;}
bool IsASomething() const { return a_ != null;}
bool IsBSomething() const{ return b_ != null;}
};
当辅助函数只以一种方式使用时(比如只检查a_是否为某物),我倾向于使用const成员函数。如果它将与几个参数一起使用,我倾向于坚持使用静态版本。还有其他我没有想到的因素会说服我做出不同的选择吗?
编辑:我认为我解释得不好,所以我在例子中添加了定义
在可能的情况下,我倾向于在未命名的命名空间中使用自由函数。
之间// header
class A
{
public:
bool HasCustomProperty() const();
private:
bool IsOdd() const;
bool IsHappy() const;
private:
int a;
};
// cpp
bool A::HasCustomProperty() const
{
return IsOdd() && IsHappy();
}
和
// header
class A
{
public:
bool HasCustomProperty() const();
private:
static bool IsOdd(int n);
static bool IsHappy(int n);
private:
int a;
};
// cpp
bool A::HasCustomProperty() const
{
return IsOdd(a) && IsHappy(a);
}
和
// header
class A
{
public:
bool HasCustomProperty() const();
private:
int a;
};
// cpp
namespace {
bool IsOdd(int n);
bool IsHappy(int n);
}
bool A::HasCustomProperty() const
{
return IsOdd(a) && IsHappy(a);
}
-
static
函数不能使用任何非静态成员函数或变量。 -
static
函数不能被多态覆盖 -
static
函数的地址 -
你不需要一个类的实例来调用
static
函数 -
标记为
const
, 的成员函数可以访问类成员,调用其他const
函数,如果标记为virtual
, 和被多态覆盖。
函数后的const
表示"此函数不修改任何类成员[除标记为mutable
的成员外]。
static
意味着"该函数没有一个隐藏的this
指针传递给该函数",所以它实际上就像任何不属于类的自由函数一样,只是它有点像"命名空间"。
它们是完全不同的"动物"。
编辑:这真的要归结为什么对职业/系统设计最有意义。对于实际上不属于类的东西,使用static
函数通常是正确的。我很少使用static
函数,因为它们除了在一些非常特殊的情况下没有什么意义——这里要问的问题是,"如果我把它设为静态,为什么它是这个类的一部分?"如果答案是"因为它属于这个类",那么它应该是一个static
函数。另一方面,如果答案不是一个可靠的理由,那么它可能不属于类,并且应该在源文件中作为静态自由函数(可能在匿名命名空间中)结束,而不是在类中。
在我的编译器项目(总共大约13000行c++代码)中,我有:
- 一个
static
成员函数(用于将字符串转换为令牌类中的关键字令牌—因为它在令牌本身的构造期间被调用,因此不适合作为成员函数)。 - 大约50个
static
函数在.cpp文件中,不是成员函数。它们的作用是:-
IsConstant()
用于某些表达式- 不,我不想把它作为表达式本身的成员函数,因为这是一个可以表达很多东西的泛型类,这意味着我必须有几十个虚函数的
return false
实现,对于一个相对罕见的情况]
- 不,我不想把它作为表达式本身的成员函数,因为这是一个可以表达很多东西的泛型类,这意味着我必须有几十个虚函数的
- 错误函数(打印错误消息)
- 可以使它们成为静态成员,但是类的用户不需要使用这些函数,这意味着将它们暴露给外部是毫无意义的。
-
它们是两个不同的东西,不能相互替换:
const成员函数不允许修改类的即时数据。静态成员函数没有关联的类实例。
使用OP的示例类定义,然后在实现…
bool Foo::IsSomething(int* n)
{
return *n < *a_; // not ok. static method has no this
}
bool Foo::IsASomething() const
{
return (*a_ > 8) // ok as member a_ not changed
}
bool Foo::IsASomething() const
{
*a_ +=4; // not ok as a_ cannot be changed by const member
return (*a_ > 8);
}