简体   繁体   English

静态与 const 成员函数

[英]static vs const member functions

I find it difficult to decide when to use private static member functions and when to use private const member functions.我发现很难决定何时使用私有静态成员函数以及何时使用私有 const 成员函数。

Let's say we have a method DoSomething() that needs to check if one or more members is something:假设我们有一个方法 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;}
};

When a helper function will only be used in one way (say only to check if a_ is something), i tend to go with a const member function.当一个辅助函数只能以一种方式使用时(比如只检查 a_ 是否是某物),我倾向于使用 const 成员函数。 If it will be used with several parameters, I tend to stick with the static version.如果它将与多个参数一起使用,我倾向于坚持使用静态版本。 Are there other factors that I haven't thought of would persuade me to choose differently?是否还有其他我没有想到的因素会说服我做出不同的选择?

Edit: I think I explained myself poorly, so I added definitions to the example.编辑:我认为我对自己的解释很差,所以我在示例中添加了定义。

  1. static functions cannot use any non-static member functions or variables. static函数不能使用任何非静态成员函数或变量。

  2. static functions cannot be overridden polymorphically. static函数不能被多态覆盖。

  3. You can take an address of a static function.您可以获取static函数的地址

  4. You don't need an instance of your class to call a static function.您不需要类的实例来调用static函数。

  5. A member function marked const , can access class members, call other const functions, and be overridden polymorphically if marked virtual .成员函数标记const可以访问类成员,调用其他const的功能,并且如果标记被重写多态virtual

const after the function means "this function does not modify any class members [except those marked mutable ]. const后面的const表示“此函数不修改任何类成员 [除了标记为mutable ]。

static means "this function does not have a hidden this pointer passed to the function", so is really just like any free function that isn't part of the class, except it's kind of "namespaced" inside the class. static意味着“此函数没有传递给函数的隐藏this指针”,因此实际上就像任何不属于该类的自由函数一样,只是它在类内部有点“命名空间”。

They are completely and utterly different "animals".它们是完全不同的“动物”。

Edit: It really comes down to what makes most sense for the class/system design.编辑:这真的归结为对类/系统设计最有意义的东西。 It is typically right to use static functions for things that are not actually part of the class as such.对于实际上不属于类的事物使用static函数通常是正确的。 I very rarely use static functions, since they make little sense except in some very special circumstances - the question to ask here is, "if I make this static, why is it part of this class at all?", and if the answer is "because it belongs on the class as it ", then it should be a static function.我很少使用static函数,因为它们没有什么意义,除非在一些非常特殊的情况下——这里要问的问题是,“如果我把它设为静态,为什么它是这个类的一部分?”,如果答案是“因为它属于类”,那么它应该是一个static函数。 On the other hand, if the answer isn't a solid reason, then it probably doesn't belong in the class and should end up as static free functions (perhaps in an anononymous namespace) in the source file, rather than in a class.另一方面,如果答案不是一个可靠的理由,那么它可能不属于类,最终应该在源文件中作为静态自由函数(可能在匿名命名空间中),而不是在类中.

In my compiler project (a total of around 13,000 lines of C++ code), I have:在我的编译器项目(总共大约 13,000 行 C++ 代码)中,我有:

  • One static member function (to translate a string into a keyword token in the token class - because it's called during the construction of the token itself, and thus isn't suitable as a member-function).一个static成员函数(将字符串转换为令牌类中的关键字令牌 - 因为它在令牌本身的构造过程中被调用,因此不适合作为成员函数)。
  • Around 50 static functions inside .cpp files that are not member functions. .cpp 文件中大约有 50 个不是成员函数的static函数。 These do things like:它们执行以下操作:
    • IsConstant() for some expression IsConstant()用于某些表达式
      • No, I don't want that as a member function of the expression itself, as that is a generic class that can express lots of things, which would mean that I'd have to have a few dozen return false implementations of a virtual function, for a relatively rare case]不,我不希望它作为表达式本身的成员函数,因为它是一个可以表达很多东西的通用类,这意味着我必须有几十个虚函数的return false实现,对于相对罕见的情况]
    • Error functions (printing an error message)错误函数(打印错误消息)
    • One could make them static members, but users of the class don't need to use these functions, which means that exposing them to the outside is pretty pointless.可以使它们成为静态成员,但类的用户不需要使用这些函数,这意味着将它们暴露给外部是毫无意义的。

I tend to use free functions in unnamed namespace when possible.如果可能,我倾向于在未命名的命名空间中使用自由函数。

So between所以之间

// 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();
}

and

// 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);
}

and

// 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);
}

I choose the last one.我选择最后一个。

They are two different things and are not alternates:它们是两种不同的东西,不是替代品:

const member functions are not allowed to modify class instant data. const 成员函数不允许修改类即时数据。 static member functions do not have an associated class instance.静态成员函数没有关联的类实例。

Using OP's example class definintion then in inplementstion ...使用 OP 的示例类定义然后在 inplementstion ...

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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM