如何初始化未使用的静态对象

How is the unused static object initialized?

本文关键字:静态 对象 未使用 初始化      更新时间:2023-10-16

代码为:

A.h

#ifndef A_H
#define A_H
class A
{
    public:
        A();
};
#endif // A_H

A.cpp

#include "A.h"
#include <iostream>
A::A()
{
    std::cout<<"A()"<<std::endl;
}
static A a;

B.h

#ifndef B_H
#define B_H
class A;
class B
{
    public:
        B();
        static A a;
};
#endif // B_H

B.cpp

#include "B.h"
#include "A.h"
A B::a;
B::B()
{
    //ctor
}

main.cpp

#include <iostream>
using namespace std;
int main()
{
    cout << "Hello world!" << endl;
    return 0;
}

下面是第一种情况,输出:

g++ main.cpp A.cpp B.cpp -o test

控制台输出为:

A()
A()
Hello world!

第二种情况,输出:

g++ main.cpp -o test

控制台输出为:

Hello world!

我对这个结果感到困惑,如果我们只是不需要在主程序中使用它们,那么本地文件中的静态对象和类中的静态成员如何初始化。

这两个对象实例都是在main被调用之前初始化的。
它们的析构函数也将在main函数执行结束后被调用。

是否使用它们实际上并不重要。而且,您在编译时没有进行任何优化。这就是为什么没有对未引用的对象进行寻址。

c++中的static关键字在多个上下文中使用。有些来自C语言,有些是新的。

旧的意思是:

int x; // this is global, it is initialized when the program is loaded
static int y; // just like global but only visible local to the file.

static的旧含义类似于全局,但仅在文件中可见。和全局变量一样,静态变量在main开始前诞生,在main结束后死亡。这就是为什么在您的示例中,在main之前调用构造函数。不幸的是,全局构造函数的顺序没有定义,这可能很麻烦。如果你需要在其他对象之前创建一些对象,你就有问题了。

当添加类时,为了不使用其他关键字,语言以相关但不同的新方式重用现有的符号。例如,引用使用&符号以一种新的方式,因为它们涉及指针。无论如何,在类中,静态意味着由整个类共享。

class A {
private:
  static int x;
};
类A中的变量x不是为A的每个实例创建的,甚至在创建类型A的第一个对象之前,x就已经存在了。它不能是全局的,因为如果它是全局的,当您将类包含在两个单独的文件中时,您将创建两个相同的全局变量(多个符号定义)

将static转换为extern。这意味着你在A中声明,有一个叫做x的符号,它是一个整数。总得有人来定义这个符号。通常,在a.c.c中:

#include "A.h"
int A::x = 0;

你不必定义x为0,因为它是一个全局变量,所以它会默认为0,但最好显式地定义它,这样每个人都能清楚地看到它。

一旦有了静态变量,就需要一个函数来访问它。静态函数在类内部,但不是方法。所以:

class A {
private:
  private static int count;
public:
  A() {
    count++; // increment count every time an object of type A is created
  }
  ~A() {
    count--;
  }
  static int getCount() { return count; }
};

查找A类对象的个数:

cout << A::getCount();

如果这个方法不是静态的,唯一的请求方式是:

A a1;
cout << a1.getCount();

所以你永远不会得到0的答案,因为为了问你必须创建a类型的对象。

你的例子的不同之处在于你创建了A类型的对象,而不是一个内置类型。