问题
Why does default initialization of static data member not occur? In the following example
struct data_member
{
data_member(){ cout << "data_member\n"; }
~data_member(){ cout << "~data_member\n"; }
};
struct Y
{
static data_member m;
Y(){ cout << "Y\n"; }
~Y(){ cout << "~Y\n"; }
};
Y y; //call constructor of Y
but if we delete static
specifier from data_member m
it will be default-initialized.
struct data_member
{
data_member(){ cout << "data_member\n"; }
~data_member(){ cout << "~data_member\n"; }
};
struct Y
{
data_member m;
Y(){ cout << "Y\n"; }
~Y(){ cout << "~Y\n"; }
};
Y y; //call Y() and data_member()
回答1:
A static member must be defined outside the class definition. It will be initialized (can be default initialized too) at that time.
The following description from the draft standard about static
member variables should explain why it is not default initialized in the class declaration.
9.4.2 Static data members
2 The declaration of a
static
data member in its class definition is not a definition and may be of an incomplete type other than cv-qualifiedvoid
. The definition for astatic
data member shall appear in a namespace scope enclosing the member’s class definition. In the definition at namespace scope, the name of thestatic
data member shall be qualified by its class name using the :: operator.
回答2:
struct Y
{
static data_member m;
Y(){ cout << "Y\n"; }
~Y(){ cout << "~Y\n"; }
};
This only declares m
. For all the compiler knows, Y::m
is defined in another translation unit. Since static data members are one-per-class, you have to be able to declare them without defining them, or you won't be able to put the class definition in a header file without violating the One Definition Rule when including the header in different translation units.
data_member Y::m;
This defines m and will cause a constructor call.
回答3:
static
data members are declared in the class
definition. They need to be defined (once) outside of that, usually in the corresponding cpp
file:
data_member Y::m;
this is where you'll see it's default ctor called.
回答4:
Basic answer: With class members it's like with functions. We have declarations and definitions. You "declare" their existence @class level and "definition" is made by constructor. With static member its more complex. They are not "instance related" and constructor will not "define" them. You have to do it by your own outside of class:
Type CLASS::member;
Btw it's quitebad practice to use static members.
Use a static function instead :
class Foo{
public:
Type &getMember(){
static Type member;
return member;
}
};
来源:https://stackoverflow.com/questions/24682349/initialization-of-static-data-member