类中的静态成员是如何分配的

How is a static member in a class allocated?

本文关键字:分配 何分配 静态成员      更新时间:2023-10-16

如果我有一个类似的类

class MyClass {
   public:
      int myMember1;
      int myMember2;
      int myMember3;
};

每次我实例化一个对象的MyClass空间,连续分配三个int,当我有类似的东西时呢

class MyClass {
   public:
      static int myMember1;
      int myMember2;
      int myMember3;
};

这次内存是如何分配的?

我之所以这么问,是因为我不完全确定当我声明同一类的多个实例时,内存将如何分配,可能有指向静态成员的指针吗?

正如其他人已经说过的,您必须在类定义之外显式地为静态成员变量分配空间。

在回答您的另一个问题时,静态成员变量与类对象不关联。也就是说,即使在MyClass对象不存在(直到程序终止)之后,它们也将继续存在,并在类的所有实例中共享。

假设您创建了MyClass类的多个实例,如下所示:

class MyClass {
public:
  static int myMember1;
  int myMember2;
  int myMember3;
};
int MyClass::myMember1 = 1;
int main()
{
   MyClass mc1;
   MyClass mc2;
   mc2.myMember1 = 2;
   std::cout << mc1.myMember1 << 'n';
   std::cout << mc2.myMember1 << 'n';
   return 0;
 }

输出为:

2
2

这次[使用静态成员]如何分配内存?

对象的每个实例中都有2个整数,并且所有实例都可以访问static整数(但不要"拥有"它)-它不是实例的一部分,而是在类的范围内。

N.B.成员在类中声明,但必须在类外(在cpp文件中)定义,例如。;

int MyClass::myMember1 = 42;

是否有指向静态成员的指针?

没有。如果需要,可以为静态成员获取一个指针,但不会为每个实例分配一个指针。

静态成员在应用程序启动时分配(并根据cpp文件中的初始化进行初始化),并且可以像其他"全局"对象一样访问(尽管静态不在全局命名空间中,但只有一个实例)。成员的可访问性(即publicprivateprotected)遵循正常规则。


要查看对大小的影响,可以使用sizeof()

class MyClass {
   public:
      int myMember1;
      int myMember2;
      int myMember3;
};
class MyClass1 {
   public:
      static int myMember1;
      int myMember2;
      int myMember3;
};
int MyClass1::myMember1 = 42;
int main(int argc, char* argv[])
{
    using namespace std;
    cout << sizeof(MyClass) << " " << sizeof(MyClass1) << endl;
}

以上(取决于int的排列和大小)可以产生12 8的输出。

演示

您还必须在类之外定义变量。这就是实际分配的地方。

本质上,它与全局变量相同。

class Test
{
    public:
    static int too; // Just a declaration
};
int Test::too; // Actual allocation, every instance will use this

您必须在某个地方显式地为该静态成员分配内存。

例如,您的类在其头文件中:

// myclass.h
class MyClass {
   public:
      static int myMember1;
      int myMember2;
      int myMember3;
};

您有一个用于该类的cpp文件,它显式地为该静态成员分配空间,它也可以初始化它:

// myclass.cpp
int MyClass::myMember1 = 5;

因此,您的静态成员将被分配在您的程序中的一个位置,即您选择的翻译单元中。您可以将此分配放入所需的任何文件中,只要它只是一个翻译单元的一部分即可。

静态内存中分配静态内存

您可以将这些成员视为全局变量,但在类范围内声明(在您的情况下,具有相应的公共访问权限)。