18

I have a confusion on class member variable initialization.

Suppose in my .h file is:

class Test {

int int_var_1;
float float_var_2;

public:
       Test();
}

My .cpp would be:

Test::Test() : int_var_1(100), float_var_2(1.5f) {}

Now when I instantiate a class the variables get initialized to 100 and 1.5.

But if that is all I'm doing in my constructor, I can do the following in my .cpp:

int Test::int_var_1 = 100;
float Test::float_var_2 = 1.5f;

I'm confused as to the difference between initializing the variables in constructors or with the resolution operator.

Does this way of initializing variables outside constructor with scope resolution only apply to static variables or is there a way it can be done for normal variables too?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
madu
  • 5,232
  • 14
  • 56
  • 96
  • 6
    The second method won't work because there's no instance and these are instance variables - they need an instance. Comparing that to C++11 in-class initialization (`class C {int i = 5;}`), this actually just fills 5 in where an initialization would otherwise take place. It doesn't actually initialize anything earlier. – chris Aug 29 '12 at 02:38

2 Answers2

21

You cannot substitute one for the other. If the member variables are not static, you have to use the initialization list (or the constructor body, but the initialization list is better suited)*. If the member variables are static, then you must initialize them in the definition with the syntax in the second block.

* Als correctly points out that in C++11 you can also provide an initializer in the declaration for non-static member variables:

class test {
   int data = 5;
};

Will have data(5) implicitly added to any initialization list where data is not explicitly mentioned (including an implicitly defined default constructor)

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • 5
    C++11 allows In-place Initialization for static members(C++11 §9.4.2.3) – Alok Save Aug 29 '12 at 03:18
  • 4
    @Als: C++11 allows for in-place initialization of **non**-static members, and the syntax would not be that of the second example, but rather in the declaration of the member. – David Rodríguez - dribeas Aug 29 '12 at 03:28
  • 1
    True that, its **non-static** members and not **static** members, just wanted to add that for completeness. – Alok Save Aug 29 '12 at 03:30
  • 1
    @Als: By the way, the reference you provided is for yet another case that I did not mention: `static const` members of integral type or `constexpr` static variables of literal types can also be initialized in the class declaration: `struct S { static const int i = 10; };` (although the definition is still required if the variable is *odr-used*. Noted the *non-static* case in the answer. – David Rodríguez - dribeas Aug 29 '12 at 03:33
  • Yes, Indeed.The reference for the *non-static* case is §12.6.2.8 and ofcourse the +1 :) – Alok Save Aug 29 '12 at 03:37
  • @DavidRodríguez-dribeas Thank you. Think I got it now. If its a non-static member variables I need must use the constructor, but if its a static variable, then I use the second method. Using the scope operator. That means even static variables are not allowed to be initialized in-class? – madu Aug 29 '12 at 04:23
  • 1
    @madu: The exact rules are not that simple, and they have become more complex in C++11. Inside the class definition you can provide value to non-static member functions (C++11 only), or `static const` variables of integral types (C++03), or `constexpr` of literal types (C++11): `struct test { int a = 5; int b; test() : b(10) {} static const int k = 15; static constexpr double d = 10.5; static int s; }; int test::s = 20;` – David Rodríguez - dribeas Aug 29 '12 at 04:29
  • Thank you David for that explanation. – madu Aug 29 '12 at 05:48
  • @DavidRodríguez-dribeas To be honest with you I think the new rules are far SIMPLER than C++03. I think they HAVE muddied up the clarity of the Constructor itself though. To a large degree they have removed its purpose, or certainly the point of supplying a custom one for your class. Although equally I have also read advice to only override the default constructor when you absolutely have to, so perhaps this helps towards that end too. –  Oct 29 '14 at 17:03
2

You should use the first method when you are initializing non-static const variables (at the constructor). That is the only way you can modify those kinds of member variables (unless you are using C++11).

Static member variables can be initialized by using proper scope resolution operators (outside the class).

Mark Garcia
  • 17,424
  • 4
  • 58
  • 94
  • Isn't EVERYONE using C++11 now - after all who can live without range-based for loops??? Humour aside - and I actually do like the new for loops - I think it is important to teach to the newest standard. Especially when so much work has gone in to improving ease-of-use. We should all be pushing C++11 as hard as possible, otherwise C# is going to gain even more ground and we C++ programmers will start heading in the direction of Perl users, post-Python. And I REALLY like Perl as well!!! –  Oct 29 '14 at 17:08
  • 1
    @GemmanAster Nope, especially for older SDKs which can't use C++11 for various reasons. – AStopher Nov 03 '14 at 09:21
  • You make a good point - but those situations must still be considered 'edge cases'. C++11 really has brought so much that is positive to the language while also eliminating a number of annoying idiosyncrasies that I really cannot think of a good reason not to adopt it - unless as you say there is a shortcoming in an SDK for a very specific platform. –  Nov 04 '14 at 00:36