【问题标题】:Static variables in static method in base class and inheritance基类和继承中的静态方法中的静态变量
【发布时间】:2011-02-13 18:52:54
【问题描述】:

我有这些 C++ 类:

class Base
{
protected:
    static int method()
    {
        static int x = 0;
        return x++;
    }
};

class A : public Base
{

};

class B : public Base
{

};

x 静态变量会在AB 之间共享,还是每个人都有自己独立的x 变量(这是我想要的)?

【问题讨论】:

  • 这不是你可以用编译器和一些测试代码快速检查的吗?
  • @ttmrichter:如果有任何怀疑,它可能与实现有关。当您检查它不是时,您已经找到了答案。
  • @ttmrichter 我怀疑该变量将被共享,但我也想看看是否有人有其他方法解决我的问题:)

标签: c++ inheritance static-methods static-variables


【解决方案1】:

整个程序中只有一个x 实例。一个很好的解决方法是使用CRTP:

template <class Derived>
class Base
{
protected:
    static int method()
    {
        static int x = 0;
        return x++;
    }
};

class A : public Base<A> { };
class B : public Base<B> { };

这将为派生自它的每个类创建一个不同的Base&lt;T&gt;,从而创建一个不同的x

正如 Neil 和 Akanksh 指出的那样,您可能还需要一个“Baser”碱基来保留多态性。

【讨论】:

  • 很好,你在我准备提交的时候发布了:)。
  • 但是如果需要的话,你没有得到的是多态性。
  • 谢谢,我忘了我在很多年前解决了一个非常相似的问题,也是用 CRTP :)
  • @neil 多态不是必需的,我只是想避免重复代码
【解决方案2】:

只有一个,由所有三个班级共享。如果您想要单独的实例,则必须在派生类中创建单独的函数。

【讨论】:

    【解决方案3】:

    前者。局部静态变量绑定到包含它们的方法,method 存在于所有子类的一个化身中(实际上,对于整个应用程序,即使程序的其余部分看不到该方法)。

    【讨论】:

      【解决方案4】:

      变量将被共享 - 它是每个函数的 - 在这种情况下,它所属的函数是 Base::method()。但是,如果 class Base 是一个模板类,您将为 class Base 模板的每个实例化(每个唯一的实际模板参数集)获得一个变量实例 - 每个实例化都是一个新函数。

      【讨论】:

        【解决方案5】:

        如果您将 X 设为静态,那么它将在所有子类之间共享。函数是静态的没有问题。

        【讨论】:

          【解决方案6】:

          我很确定它将在 A 和 B 之间共享。

          如果你想要独立变量,你可以使用“Curiously Recurring Template Pattern”,比如:

          template<typename Derived>
          class Base
          {
          protected:
              static int method()
              {
                  static int x = 0;
                  return x++;
              }
          };
          
          class A : public Base<A>
          {
          
          };
          
          class B : public Base<B>
          {
          
          };
          

          当然,如果你想要多态性,你必须定义一个基数派生的偶数“Baser”类,因为Base&lt;A&gt;Base&lt;B&gt; 不同,例如:

          class Baser
          {
          };
          
          template<typename Derived>
          class Base : public Baser
          {
          protected:
              static int method()
              {
                  static int x = 0;
                  return x++;
              }
          };
          
          class A : public Base<A>
          {};
          
          class B : public Base<B>
          {};
          

          现在 A 和 B 也可以是多态的。

          【讨论】:

            猜你喜欢
            • 2017-02-07
            • 2012-07-17
            • 2015-05-16
            • 1970-01-01
            • 2012-11-21
            • 2020-10-18
            • 2022-10-06
            • 2011-06-26
            • 1970-01-01
            相关资源
            最近更新 更多