How to Initialize Const Member Variable in a Class

How to initialize const member variable in a class?

The const variable specifies whether a variable is modifiable or not. The constant value assigned will be used each time the variable is referenced. The value assigned cannot be modified during program execution.

Bjarne Stroustrup's explanation sums it up briefly:

A class is typically declared in a header file and a header file is typically included into many translation units. However, to avoid complicated linker rules, C++ requires that every object has a unique definition. That rule would be broken if C++ allowed in-class definition of entities that needed to be stored in memory as objects.

A const variable has to be declared within the class, but it cannot be defined in it. We need to define the const variable outside the class.

T1() : t( 100 ){}

Here the assignment t = 100 happens in initializer list, much before the class initilization occurs.

How to initialize a const member variable of a class with a const variable?

You have to use member initializer list for that:

myClass(const int id)
: ID(id) { }

How to set a const member variable in a C++ class on construction?

Use an initializer list in the constructor.

class myRectangle {
private:
const int length; //const mainly for "read-only" like
const int breadth; //protection
public:
myRectangle(int init_length, int init_breadth) :
length(init_length), breadth(init_breadth)
{
// rest of constructor body can go here; `length` and `breadth`
// are already initialized by the time you get here
}
int calcArea(void);
void turn90Degrees(void);
};

How to initialize const member requiring computations to be performed?

Use a function call inside a delegating (if avaliable, not neccessarily) constructor's member initialization list:

A::A(std::string const& yourstring) : A(compute_myint(yourstring)) {};

Pass std::string by const&, not just const, while you're at it.

compute_myint can be non-member, static member, possibly not accessible from outside the class, whichever makes the most sense.

Initialize const member variables

If you can afford a C++11 compiler, consider delegating constructors:

class Foo
{
// ...
bool const bar;
bool const baz;
Foo(void const*);
// ...
Foo(my_struct const* s); // Possibly private
};

Foo::Foo(void const* ptr)
: Foo{complex_method(ptr)}
{
}

// ...

Foo::Foo(my_struct const* s)
: bar{calculate_bar(s)}
, baz{calculate_baz(s)}
{
}

As a general advice, be careful declaring your data members as const, because this makes your class impossible to copy-assign and move-assign. If your class is supposed to be used with value semantics, those operations become desirable. If that's not the case, you can disregard this note.

C++ Initialize const class member variable in header file or in constructor?

They both are not exacly the same, with the constructor initialisation one disadvantage is that you need to maintain the order of initialisation
Also if you use .cpp and .h, you may need to always switch to cpp to find the initialised values.

This is already answered in this question C++11 member initializer list vs in-class initializer?

Common solution for initializing const member variable in abstract base class

You could have a const double& in your base class and store the double in your derived class. Something like this.

#include <iostream>

struct Foo {
Foo(const double& ref) : value(ref) {}
const double& value;
};

struct Bar : Foo {
Bar(const double p1, const double p2) : Foo (value), value(p1 + p2) {}

private:
double value;
};

int main() {
Bar b(5, 3);

Foo* f = &b;

std::cout << f->value;
}

Here Bar is allowed to modify value, but since Base has a const ref you can't modify the value using the reference.

If you need Bar::value to be const as well, you would need to initialize it in the constructor initializer list. If you additionally require a function to calculate that value it can't be a member function, since you can't call a member function before the object has been constructed.

In that case you could make Calc_value a static member function and pass it the parameters it needs from the constructor of Bar

struct Bar : Foo {
Bar(const double p1, const double p2) : Foo (value), value(Calc_value(p1, p2)) {}

private:
static double Calc_value(const double p1, const double p2) {
return p1 + p2;
}
double value;
};

It just seems like you are making you code a bit overly complicated just to avoid writing () at this point.

Are there advantages of using const member variable in C++

A practical advantage of const members is that unless they're of a class with user defined default constructor, they have to be explicitly initialized. So a ¹standard-conforming compiler will catch any missing initialization. It's also an advantage that const members express the intended functionality, namely no change over the lifetime of an object, and so help the compiler to detect any code that otherwise would (erroneously) change the values.

On the other hand, which can more important, with the default functionality they prevent copy assignment and moving.

These considerations also apply to reference data members, which can be regarded (conceptually) as auto-dereferenced const pointer members.


For client code, but not the class' own code, the logical const-ness, the immutability, can be expressed by using non-public non-const data members with const accessor member functions.



¹ Unfortunately Visual C++ 2015 accepts at least some cases of uninitialized const member that doesn't have a user-defined default constructor, so as of this writing one can't be 100% sure that the compiler will catch missing initializations.

Initializing const member variables of a singleton

In order to initialize a const member of an object, you must do it in the initializer list of the constructor. That means you are forced to make it part of the instance function. You can layer this so that instance doesn't take a parameter, but calls create_instance which does.

Singleton(const vector<A*> * init) : as(*init)
{
}

Singleton& create_instance(const vector<A*> * init)
{
static Singleton instance(init);
return instance;
}

Singleton& instance()
{
return create_instance(null_ptr);
}

For completeness you should put some error checking that throws an exception if create_instance is called more than once with a non-null parameter.



Related Topics



Leave a reply



Submit