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

时间:2014-07-19 03:43:25

标签: c++

代码是:

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!

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

2 个答案:

答案 0 :(得分:1)

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

无论您是否使用实际上并不重要。此外,您正在编译而没有优化。这就是未引用的对象未被解决的原因。

答案 1 :(得分:0)

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.

静态的旧含义就像一个全局,但仅在文件中可见。 与全局变量一样,静态变量在主要开始之前出现,并在结束之后死亡。这就是为什么在您的示例中,构造函数在main之前调用。不幸的是,没有定义全局构造函数的顺序,这可能是一种痛苦。如果您需要在其他对象之前创建某些对象,则会出现问题。

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

class A {
private:
  static int x;

};

不为A的每个实例创建A类内的变量x。甚至在创建类型A的第一个对象之前,x就存在。它不可能是全局的,因为如果它是,当你将类包含在两个单独的文件中时,你将创建两个相同的全局变量(多个符号定义)

相反,静态变成了外部。这意味着您在A中声明了一个名为x的符号,它是一个整数。有人必须定义该符号。通常,在A.cc:

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

你不必定义x是零,它无论如何都是默认的,因为它是一个全局的,但是明确定义它总是更好,所以对每个人来说都很明显。

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

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类型的对象而不是内置类型。