【问题标题】:Const static member functions: is another approach available?const 静态成员函数:是否有另一种方法可用?
【发布时间】:2020-01-17 11:15:04
【问题描述】:

正如this Q&A 中所报告的,const 静态成员函数在 C++ 中是/不可用的。从那以后(2011 年)有什么变化吗?

是否有另一种方法可以让静态成员函数不修改其类的静态成员?

类似(伪代码):

class C
{
   static int a;
public:
   static void Incr() { ++a; }
   static int  Ret() const { return a; }
};

int C::a = 0;

我需要从另一个类的 const 成员函数中调用 [const] 静态成员函数。

【问题讨论】:

  • 您可以将所有静态数据移动到一个类的静态实例中,并拥有该类的 const 成员函数。
  • 在一般情况下,您无法真正检查全局变量的 constness。想象一下static void C::Foo() const { ::bar(); Ret(); }void ::bar() {C::Incr();}
  • 如果你停止使用全局状态,所有这些问题都会消失,就像@Brian 建议的那样。

标签: c++ constants static-methods


【解决方案1】:

根据目前cppreference.com(关于static members的页面),静态成员函数仍然不能是const,因为const关键字只修改了this指针,而静态函数显然没有。

所以自从你提到的答案被写出来之后,似乎什么都没有改变。

【讨论】:

    【解决方案2】:

    自那以后(2011 年)有什么变化吗?

    没有改变,你仍然不能对静态成员函数进行 cv 限定。

    是否有另一种方法可以让静态成员函数不修改其类的静态成员?

    不是一个完美的解决方案,但您可以为静态数据成员声明 const “别名”:

    static int  Ret() { 
        static constexpr const auto& a = C::a;
        // Now C::a is shadowed by the local a
        // and the function can't modify it.
        // a = 2; // ill-formed
        return a * 2; // OK
    }
    

    它仍然需要纪律,但至少这样编译器可以捕捉到意外的修改尝试。

    【讨论】:

    • 我喜欢这会导致编译错误,但我不喜欢函数签名没有(/不必)反映这种行为
    • @eike - 我听到了。我也知道 OP 的来源。但这是我能想到的最接近的近似值。
    • 虽然不是真正可扩展的,但应该为每个静态成员完成,对于所有静态 const 方法:-/
    • @Pietro - 什么get?我不能告诉你你在我看不到的代码上做错了什么。
    • @pietro - 我现在明白了。我犯了复制粘贴错误。现在删除了错误的位。不要 const 限定方法本身。这完全是非法的。
    【解决方案3】:

    只有静态字段和静态方法的类不配称为类。它只是具有花哨名称间距的函数和全局变量的形式。

    无论如何,IMO 最好有一个具有常规字段和方法的常规类,然后将其实例化为全局变量(不是很好的解决方案,但至少在类仅包含静态字段和方法的情况下更诚实)。

    class C
    {
       int a;
    public:
       C() : a(0) {}
       void Incr() { ++a; }
       int  Ret() const { return a; }
    };
    
    C instance;
    

    或者使用我讨厌的单例模式。

    从生成代码的角度来看应该没有区别。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-02
      • 1970-01-01
      • 1970-01-01
      • 2017-10-11
      • 1970-01-01
      • 1970-01-01
      • 2012-03-31
      相关资源
      最近更新 更多