Reputation: 7397
I came across a statement in my book that said:
You don't have to initialize a static member when you declare it; C++ will invoke the default constructor if you don't.
This really has me confused as to what it means. Are they talking about object members only? If so, at what point would it call the default constructor? Also, how would you initialize a static member object without the default constructor?
Upvotes: 9
Views: 27839
Reputation: 980
In this statement: "You don't have to initialize a static member when you declare it; C++ will invoke the default constructor if you don't." "The static member" means the "static member" of some primitive types member variable, in another word, the data types of the "static member" should only be: int, float, or char..... So for these primitive types, compiler know their "default constructor", e.g. for the "int" type, compiler just set 0. But if these static members types are specific classes, not those C++ built-in primitive types, you must call the specific constructor function explicitly, it's exactly same as the 1st answer provided by "Kerrek SB" But remember one thing, even your static member's type is primitive type, you still need declare its implementation in the *.c file. Assume in the example provided by "Kerrek SB", if we change the:
class Star
{
static Foo z;
// ...
};
to
class Star
{
static int z;
// ...
};
in the star.h file, we still need to add one line in star.c as:
// again in star.cpp
int Star::z;
It'll be initialized as 0 by compiler; So I believe the "static member" in in "You don't have to initialize a static member" only means "static member" whose type is C++ primitive type. If its type are some classes, you must call their specific constructor function as same as any other classes' objects.
Upvotes: 1
Reputation: 16197
Edit: Moving the comment to answer.
member is by definition always an object member as it means a declared variable as a member of an object. That said static members need to be forward declared and it's generally good practice to explicitly initialize variables. What book is this?
// SomeObject.h
class SomeObject
{
public:
SomeObject(); // default constructor
private:
// declare members
int m_intMember;
static int m_staticIntMember;
};
// SomeObject.cpp
#include "SomeObject.h"
// forward declaration and initializing of static member
int SomeObject::m_staticIntMember(42);
SomeObject::SomeObject() : m_intMember(7) // initializing other member
{
}
Upvotes: 1
Reputation: 477010
Let's break it down. Suppose there's some class Foo;
somewhere. Now we make this a static member of our class,
class Star
{
static Foo z;
// ...
};
Now in essence that declares a global object Foo Star::z
-- so how does this get instantiated? The standard tells you: it gets default-constructed. But remember that you have to provide the actual object instance in one of your translation units:
// in, say, star.cpp
Foo Star::z; // OK, object lives here now
Now suppose that Foo
doesn't actually have a default constructor:
class Foo
{
public:
Foo(char, double); // the only constructor
// ...
};
Now there's a problem: How do we construct Star::z
? The answer is "just like above", but now we have to call a specific constructor:
// again in star.cpp
Foo Star::z('a', 1.5);
The standard actually has two distinct notions of "initialization" (a grammatical concept) and "construction" (a function call), but I don't think we need to go into this just now.
Upvotes: 18
Reputation: 283634
In C++, new objects are always initialized somehow. There's default initialization, copy initialization, value initialization, and direct initialization, the only question is which one your code is using.
I assume they mean:
SomeObject SomeClass::x; // default initialization, class types will have the default constructor called
vs
SomeObject SomeClass::x = blah; // copy initialization
The copy constructor is needed, possibly there's also a conversion of blah
to a temporary SomeObject
before calling the copy constructor, and sometimes the call to the copy constructor is skipped, but it must be accessible.
If you don't want to call the default or copy constructor, use direct initialization syntax:
SomeObject SomeClass::x(blah); // direct initialization
Upvotes: 2