149
#include <iostream>

using namespace std;
class T1
{
  const int t = 100;
  public:
  
  T1()
  {
    cout << "T1 constructor: " << t << endl;
  }
};

When I am trying to initialize the const data member t with 100. But it's giving me the following error:

test.cpp:21: error: ISO C++ forbids initialization of member ‘t’
test.cpp:21: error: making ‘t’ static

How can I initialize a const member?

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
Chaitanya
  • 3,399
  • 6
  • 29
  • 47
  • 15
    with c++11 this is possible check this link http://stackoverflow.com/questions/13662441/c11-allows-in-class-initialization-of-non-static-and-non-const-members-what-c – PapaDiHatti May 30 '16 at 08:10
  • c++11 support brace or equals initializer included in the member declaration – Cauchy Schwarz Feb 02 '21 at 17:26

12 Answers12

153

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.

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
Dinkar Thakur
  • 3,025
  • 5
  • 23
  • 35
  • 6
    Can you be a bit elaborate on the last statement `Here the i = 10 assignment in initializer list happens much before the class initilizaiton occurs.` I dint get this. And basically that kind of allowing definitions within the class is compiler specific right ? – Chaitanya Jan 24 '13 at 07:31
  • I have constants in my class that I initialise in the above way. However, when I try to create an object of that class, it gives me an error saying that `operator = function not found` in VC++. What can be the problem? – Rohit Shinde Oct 26 '14 at 15:30
  • 5
    When you use someone's exact words without attribution, it is called plagiarism. Please use proper attribution - see http://www.stroustrup.com/bs_faq2.html#in-class and http://stackoverflow.com/questions/13662441/c11-allows-in-class-initialization-of-non-static-and-non-const-members-what-c – Tanaya Oct 11 '15 at 03:04
  • Yeah, I also totally don't understand the code in the answer - what the hell is that? Can it be placed in cpp file implementation? – Tomáš Zato Dec 01 '15 at 15:56
  • Nice explanation. But it might be worth adding that only `static const int` are allowed to be initialized inside class declaration itself. – ViFI Jun 29 '16 at 18:19
  • I would have used a different wording: "const specifies whether a variable is read only" or that "const specifies weather a variable is modifiable by your the code or not". Think of "const volatile int myVar" which specifies that you can read from myVar but myVar can change. – Sil Feb 26 '17 at 19:19
  • Good answer but would be a better answer if you showed showed the whole class properly defined, even though it's shown in the question, to avoid confusion, scrolling, misinterpretation, etc... – clearlight Oct 22 '18 at 14:40
  • It's a good explanation, but imho its non-orthogonal with respect with what you can do with functions in the stack. memory is memory and ops are ops. This is in my opinion quite quirky, and leads developers to not consider data structures for meaningful work. damage done. – Kalen Dec 03 '21 at 20:19
65

Well, you could make it static:

static const int t = 100;

or you could use a member initializer:

T1() : t(100)
{
    // Other constructor stuff here
}
Fred Larson
  • 60,987
  • 18
  • 112
  • 174
  • 2
    For his use (and/or intentions), it would be much better to to make it static. – Mark Garcia Jan 24 '13 at 07:01
  • @FredLarson Is it like some g++ versions doesn't allow that kind of initializations ? or It is not permitted at all ? – Chaitanya Jan 24 '13 at 07:11
  • 3
    @Chaitanya: C++11 Non-static member initializers are implemented from gcc 4.7. – Jesse Good Jan 24 '13 at 07:31
  • @MarkGarcia why much better? it could be on requirement if `const member` should be accessible from the functions/objects then why static? – Asif Mushtaq Feb 10 '16 at 16:28
  • 1
    Though usually it is misleading to give an example to beginners of static. Because, they may not know it is only one for all instances (objects) of that class. – Silidrone Aug 19 '17 at 21:27
  • @MuhamedCicak: If it's `const`, what difference does it make? – Fred Larson Aug 19 '17 at 22:34
  • @FredLarson Actually, after reading [this](https://stackoverflow.com/questions/3904759/how-can-i-initialize-a-const-variable-of-a-base-class-in-a-derived-class-constr), I can admit with you. I did not know it was illegal in C++. – Silidrone Aug 19 '17 at 23:02
43

There are couple of ways to initialize the const members inside the class..

Definition of const member in general, needs initialization of the variable too..

1) Inside the class , if you want to initialize the const the syntax is like this

static const int a = 10; //at declaration

2) Second way can be

class A
{
  static const int a; //declaration
};

const int A::a = 10; //defining the static member outside the class

3) Well if you don't want to initialize at declaration, then the other way is to through constructor, the variable needs to be initialized in the initialization list(not in the body of the constructor). It has to be like this

class A
{
  const int b;
  A(int c) : b(c) {} //const member initialized in initialization list
};
peterflynn
  • 4,667
  • 2
  • 27
  • 40
ravs2627
  • 811
  • 8
  • 3
  • 17
    I think this answer needs clarification. Use of the static keyword for a class member is not adding some arbitrary syntax to make the compiler happy. It means there is a single copy of the variable for all instances of the object, constant or not. It is a design choice that needs to be considered carefully. Down the line the programmer might decide this constant class member could still vary with different objects, despite remaining constant for the lifetime of a given object. – opetrenko Jul 16 '14 at 15:38
  • Agreed ..When we use static, it creates just one copy of it for all the objects.. As you mentioned its a design choice. In case of single copy for all objects 1 and 2 should work. In case of individual copy for each object, 3 would work – ravs2627 Aug 04 '14 at 13:19
  • This answer suggests a simple syntax change without consequences - whereas changing it to be static is not. – Isaac Woods Nov 09 '15 at 17:25
  • what if you need to use double or float - is this a part of the C++11 standard? – serup Feb 05 '19 at 08:54
23

If you don't want to make the const data member in class static, You can initialize the const data member using the constructor of the class. For example:

class Example{
      const int x;
    public:
      Example(int n);
};

Example::Example(int n):x(n){
}

if there are multiple const data members in class you can use the following syntax to initialize the members:

Example::Example(int n, int z):x(n),someOtherConstVariable(z){}
FortyTwo
  • 2,414
  • 3
  • 22
  • 33
GANESH B K
  • 381
  • 3
  • 5
  • 5
    I think this provides a better answer than the one that was accepted.... – Ian Nov 03 '17 at 09:38
  • 2
    Thank you for the crystal clear examples, and the variant showing a plurality! Eliminated ambiguity and extra research/scrolling on the part of the reader! – clearlight Oct 22 '18 at 14:42
14
  1. You can upgrade your compiler to support C++11 and your code would work perfectly.

  2. Use initialization list in constructor.

    T1() : t( 100 )
    {
    }
    
Pang
  • 9,564
  • 146
  • 81
  • 122
borisbn
  • 4,988
  • 25
  • 42
9

Another solution is

class T1
{
    enum
    {
        t = 100
    };

    public:
    T1();
};

So t is initialised to 100 and it cannot be changed and it is private.

Pang
  • 9,564
  • 146
  • 81
  • 122
Musky
  • 91
  • 1
  • 6
3

If a member is a Array it will be a little bit complex than the normal is:

class C
{
    static const int ARRAY[10];
 public:
    C() {}
};
const unsigned int C::ARRAY[10] = {0,1,2,3,4,5,6,7,8,9};

or

int* a = new int[N];
// fill a

class C {
  const std::vector<int> v;
public:
  C():v(a, a+N) {}
};
Viet Anh Do
  • 449
  • 5
  • 6
2

Another possible way are namespaces:

#include <iostream>

namespace mySpace {
   static const int T = 100; 
}

using namespace std;

class T1
{
   public:
   T1()
   {
       cout << "T1 constructor: " << mySpace::T << endl;
   }
};

The disadvantage is that other classes can also use the constants if they include the header file.

Baran
  • 31
  • 4
1

This is the right way to do. You can try this code.

#include <iostream>

using namespace std;

class T1 {
    const int t;

    public:
        T1():t(100) {
            cout << "T1 constructor: " << t << endl;
        }
};

int main() {
    T1 obj;
    return 0;
}

if you are using C++10 Compiler or below then you can not initialize the cons member at the time of declaration. So here it is must to make constructor to initialise the const data member. It is also must to use initialiser list T1():t(100) to get memory at instant.

quant
  • 2,184
  • 2
  • 19
  • 29
Gambler Aziz
  • 41
  • 1
  • 10
1

In C++ you cannot initialize any variables directly while the declaration. For this we've to use the concept of constructors.
See this example:-

#include <iostream>

using namespace std;

class A
{
    public:
  const int x;  
  
  A():x(0) //initializing the value of x to 0
  {
      //constructor
  }
};

int main()
{
    A a; //creating object
   cout << "Value of x:- " <<a.x<<endl; 
   
   return 0;
}

Hope it would help you! Please do Upvote

MolyOxide
  • 59
  • 1
  • 1
  • 11
0

you can add static to make possible the initialization of this class member variable.

static const int i = 100;

However, this is not always a good practice to use inside class declaration, because all objects instacied from that class will shares the same static variable which is stored in internal memory outside of the scope memory of instantiated objects.

dhokar.w
  • 386
  • 3
  • 6
0

In 2023 your example compiles now without any errors. There is no need to use an initialization list or to make the variable static. I compiled and run your identical code with:

g++ -std=c++11 -Wall -Wpedantic -Wextra -Werror -Wuninitialized -Wsuggest-override test.cpp

I use:

~$ g++ --version
g++ (Debian 10.2.1-6) 10.2.1 20210110
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Ingo
  • 588
  • 9
  • 21