26

Where is the correct place to initialize a class data member? I have the class declaration in a header file like this:

Foo.h:

class Foo {
private:
    int myInt;
};

Then I try to set a value to myInt in the corresponding .cpp file:

Foo.cpp:

int Foo::myInt = 1;

I get a compiler error for redefining myInt. What am I doing wrong???

Tony R
  • 11,224
  • 23
  • 76
  • 101

5 Answers5

38

What you have there is an instance variable. Each instance of the class gets its own copy of myInt. The place to initialize those is in a constructor:

class Foo {
private:
    int myInt;
public:
    Foo() : myInt(1) {}
};

A class variable is one where there is only one copy that is shared by every instance of the class. Those can be initialized as you tried. (See JaredPar's answer for the syntax)

For integral values, you also have the option of initializing a static const right in the class definition:

class Foo {
private:
    static const int myInt = 1;
};

This is a single value shared by all instances of the class that cannot be changed.

Eclipse
  • 44,851
  • 20
  • 112
  • 171
  • 4
    Hi, can you tell me what is the name of the `Foo() : myInt(1) {}` syntax, so I can Google it and read in more detail? Is it the same as `public: Foo() { myInt = 1; }`? – SexyBeast Nov 08 '14 at 10:52
  • 7
    @Cupidvogel: They are "Member initializer lists" (http://en.cppreference.com/w/cpp/language/initializer_list) – Eclipse Nov 08 '14 at 16:08
13

To extend on Jared's answer, if you want to initialize it the way it is now, you need to put it in the Constructor.

class Foo
{
public:
    Foo(void) :
    myInt(1) // directly construct myInt with 1.
    {
    }

    // works but not preferred:
    /*
    Foo(void)
    {
        myInt = 1; // not preferred because myInt is default constructed then assigned
                   // but with POD types this makes little difference. for consistency
                   // however, it's best to put it in the initializer list, as above
                   // Edit, from comment: Also, for const variables and references,
                   // they must be directly constructed with a valid value, so they
                   // must be put in the initializer list.
    }
    */

private:
    int myInt;
};
GManNickG
  • 494,350
  • 52
  • 494
  • 543
  • 1
    Good for explaining +1 method, describing advantages/disadvantages, and for describing the terminology of the "initializer list" (which looks very different than accepted answer's description " in a constructor" to programmers coming from other languages; "in a constructor' is between the constructor's curly brackets. And this answer sums it all up for me. – Nate Anderson Apr 19 '17 at 01:51
11

It can be initialized directly in the header file, in c++11 or gnu++11:

int myInt = 1;

See this article "C++11 Tidbits: Non-static Data Member Initializers"

Zoe
  • 27,060
  • 21
  • 118
  • 148
user1914692
  • 3,033
  • 5
  • 36
  • 61
5

You're attempting to initialize an instance member via a static initialization construct. If you want this to be a class level variable (static) then precede the variable with the static keyword.

class Foo {
private:
  static int myInt;
};
NHDaly
  • 7,390
  • 4
  • 40
  • 45
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • Thanks! I'm assuming a "class-level variable" is one that can only be used within a class and nowhere else? – Tony R Apr 06 '09 at 19:38
  • @draftomatic, by class-level variable i meant one which is not associated with an instance of the class. Within only Foo (and it's friends) you can simply say Foo::myInt. No instance of Foo is required. – JaredPar Apr 06 '09 at 19:40
2

A class variable must be marked as "static". If your variable is an instance variable and not a class variable you must initialize it in the constructor or other method.

Fabio Vinicius Binder
  • 13,024
  • 4
  • 34
  • 33