Variable instantiation

I am confused about some feedback I got:

"Member variables should be instantiated in the class constructor, not the declaration."

I declared the variable under private: in the header file. Is the feedback saying I should have declared it in the .cpp file instead?
I have no idea what that's saying. Members of an object are instantiated automatically when the object is instantiated.

Can you give us some more context? Cause without that, it's hard to know what you're talking about.
Some context? What do you mean by context? There is a .cpp file and .h file. I created two functions in the .cpp file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void SettingsPresenter::setProgressWizardBool(int requestedValue)
{
    if (m_progressWizardBool == requestedValue)
    {
        return;
    }

    m_progressWizardBool = requestedValue;
    emit progressWizardBoolChanged();
}

bool SettingsPresenter::getProgressWizardBool() const
{
    return m_progressWizardBool;
}


then I instantiated the variable: m_progressWizardBool in the header file:

1
2
3
private:
...
   bool m_progressWizardBool = false;


and this is the feedback I got. I am not sure what he is asking me to do or why. I have to admit I am rather new to C++ programing. The reviewer is not around for contact. Does this help with context?
Last edited on
You need to assign your member variables some value when you instantiate your class.

SomeClass.hpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef __SOMECLASS_HPP__
#define __SOMECLASS_HPP__

class SomeClass
{
private:
   int var1;
   int var2;

public:
    SomeClass();
   ~SomeClass() { }

public:
   int Get1() const { return var1; }
   int Get2() const { return var2; }
};
#endif 


SomeClass.cpp
1
2
3
#include "SomeClass.hpp"

SomeClass::SomeClass() : var1(10), var2(20) { }


An older way to define your member data in the constructor:
1
2
3
4
5
6
7
#include "SomeClass.hpp"

SomeClass::SomeClass()
{
   var1 = 10;
   var2 = 20;
}


Now let's use the class (either ctor version):
1
2
3
4
5
6
7
8
9
#include <iostream>
#include "SomeClass.hpp"

int main()
{
   SomeClass sc;

   std::cout << sc.Get1() << ' ' << sc.Get2() << '\n';
}

10 20


C++11 (and later) allowed direct member data initialization in the class declaration:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef __SOMECLASS_HPP__
#define __SOMECLASS_HPP__

class SomeClass
{
private:
   int var1 = 5;
   int var2 = 25;

public:
    SomeClass();
   ~SomeClass() { }

public:
   int Get1() const { return var1; }
   int Get2() const { return var2; }
};
#endif 

Now the ctor is not required to initialize the data members:
1
2
3
#include "SomeClass.hpp"

SomeClass::SomeClass() { }

No change to your driver source code required, and output is:
5 25


You can define another ctor that takes some values to set your member data to values other than the default:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef __SOMECLASS_HPP__
#define __SOMECLASS_HPP__

class SomeClass
{
private:
   int var1 = 5;
   int var2 = 25;

public:
    SomeClass() { }
    SomeClass(int, int);
   ~SomeClass() { }

public:
   int Get1() const { return var1; }
   int Get2() const { return var2; }
};
#endif 

1
2
3
#include "SomeClass.hpp"

SomeClass::SomeClass(int one, int two) : var1(one), var2(two) { }

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include "SomeClass.hpp"

int main()
{
   SomeClass sc;

   std::cout << sc.Get1() << ' ' << sc.Get2() << '\n';

   SomeClass sc2(101, 89);

   std::cout << sc2.Get1() << ' ' << sc2.Get2() << '\n';
}

5 25
101 89


C++11 added a new way to initialize variables, uniform initialization:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef __SOMECLASS_HPP__
#define __SOMECLASS_HPP__

class SomeClass
{
private:
   int var1 { 5 };
   int var2 { 25 };

public:
    SomeClass() { }
    SomeClass(int, int);
   ~SomeClass() { }

public:
   int Get1() const { return var1; }
   int Get2() const { return var2; }
};
#endif 
In your first post, all you mentioned was that you got feedback. You didn't say from what. I assumed you were talking about a compiler warning, until you made your second post.

Your reviewer is giving an opinion but acting like it's fact. There's nothing wrong with doing bool m_progressWizardBool = false;.

But if you want to make your reviewer happy, then do something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Example program

class Foo {
  public:
    Foo()
    : my_bool(false)
    {
     
    }
  
    bool my_bool;  
};

int main()
{
    Foo foo; // my_bool wil be initialized to false
}
@Furry Guy I will try to deconstruct what you are saying but I am assuming you and Genado are explaining the same thing?

@Genado Okay great, could you explain what the difference is? Perhaps deconstruct your code a bit with comments so I can understand what is happening?
Last edited on
Wait... when you say "instantiate", do you really mean "initialise"? Because that would make the comment a lot more comprehensible.

So... just to be precise, when you specify a value for a member in the class declaration, like so:

1
2
3
private:
//...
   bool m_progressWizardBool = false;

what you're technically doing is specifying a default initial value for the member. If you don't explicitly initialise the member to a value, then it will be initialised by default to the value you've put in the class declaration.

There's nothing wrong with doing it that way. However, whoever is reviewing your code (you don't say who that is) doesn't seem to like you doing it that way, and prefers you to use an intialiser list in the constructor, just like Ganado, and FurryGuy in his first example, show you. This is the traditional way, that's been part of C++ from the beginning, and any textbook or tutorial will explain this as a way to initialise your variables.

We can't know why your reviewer doesn't want you to do it the way you did. But if they're no longer around to give any further communication, why care about their unexplained preferences?
Last edited on
@MilkeyBoy I am not sure; this is one of the reasons I was confused. I am assuming he meant to say 'initialized' as, as far as I remember, variables are initialized and objects are instantiated.
@Ganado I am getting an error:

runtime error: load of value 190, which is not a valid value for type 'bool'

The program compiles just fine and it all works here is what I wrote:

1
2
3
4
5
6
7
8
9
public:

    SettingsPresenter()
        : m_progressWizardBool(false)
    {

    }

    bool m_progressWizardBool;


EDIT: My mistake the error is actually coming from the .cpp file:

1
2
3
4
5
6
7
8
9
10
11
12
13
void SettingsPresenter::setProgressWizardBool(bool requestedValue)
{
    if (m_progressWizardBool != requestedValue) // <- error here
    {
      m_progressWizardBool = requestedValue;
      emit progressWizardBoolChanged();
    }
}

bool SettingsPresenter::getProgressWizardBool() const
{
    return m_progressWizardBool; // <- error here
}
Last edited on
Strange... in the debugger it says that m_progressWizardBool's type is bool but it's value is -66?
I understand now, the mistake I made. I should have defined in the header:
1
2
3
4
5
public:
    SettingsPresenter();
...
private:
m_progressWizardBool;

and then in the .cpp file:
1
2
SettingsPresenter::SettingsPresenter()
  : m_progressWizardBool(false)

I had it all defined in the header.
Last edited on
as far as I remember, variables are initialized and objects are instantiated.

Objects and variables are both instantiated.

Objects and variables are both initialised.
Last edited on
Topic archived. No new replies allowed.