C++ class static member variable definition

Hi, I am doing my book book problem right now, "C++ from control structures through objects". I am learning more about classes right now. The first chapter of "More about classes" is about static member variable and static member function. I am kinda confused about how I should define static member variable. In the book, it obviously says that I need to do two things for static member variable. First, I have to define static member variable with the keyword "static" inside that class under private:, and as a second thing I need to initialize outside of class. Here is my code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  #ifndef NUMBER_H
#define NUMBER_H
#include<iostream>
#include <string>
using namespace std;

class Number
{
private:
 int number;
 
 static string lessThan20[20]; 
 static string restTens[7];
 static string hundreds; 
 static string thousands;
 
 public:
 
 Number(int);
 void print();
 string translator(int);
 




};

string Number::lessThan20[20] = { "zero","one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"};
string Number::restTens[7] = {"thirty","fourty","fifty","sixty","seventy","eighty","ninety"};
string Number::hundreds ="hundreds";
string Number::thousands="thousands";

#endif 


I keep getting error message following:
/usr/bin/ld: /tmp/ccWCACvB.o:(.bss+0x0): multiple definition of `Number::lessThan20[abi:cxx11]'; /tmp/ccOtAGWA.o:(.bss+0x0): first defined here
/usr/bin/ld: /tmp/ccWCACvB.o:(.bss+0x280): multiple definition of `Number::restTens[abi:cxx11]'; /tmp/ccOtAGWA.o:(.bss+0x280): first defined here
/usr/bin/ld: /tmp/ccWCACvB.o:(.bss+0x360): multiple definition of `Number::hundreds[abi:cxx11]'; /tmp/ccOtAGWA.o:(.bss+0x360): first defined here
/usr/bin/ld: /tmp/ccWCACvB.o:(.bss+0x380): multiple definition of `Number::thousands[abi:cxx11]'; /tmp/ccOtAGWA.o:(.bss+0x380): first defined here
collect2: error: ld returned 1 exit status

I am using ubuntu g++ compiler. What am I doing wrong ?? I mean it doesn't get error without initialization that is outside of class but I need this definition and I tried to do it inside of class too but didn't work either. What am I supposed to do?
You made the definition in the header file, so every .cpp file that uses it, generates a definition. At link time, the linker sees multiple definitions, complains and stops.

With C++17 you can use a different syntax:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Number {
private:
    int number;
 
    inline static std::string lessThan20[] = {
        "zero","one","two","three","four","five","six",
        "seven","eight","nine","ten","eleven","twelve","thirteen","fourteen",
        "fifteen","sixteen","seventeen","eighteen","nineteen"};
    inline static std::string restTens[] = {"thirty","fourty","fifty","sixty","seventy","eighty","ninety"};
    inline static std::string hundreds{"hundreds"};
    inline static std::string thousands{"thousands"};

public:
    Number(int);
    void print();
    std::string translator(int);
};
I have to define static member variable with the keyword "static" inside that class [... and] initialize outside of class

Either you misread the book, or it is wrong -- very possible.

Consider this program:
1
2
3
4
5
6
struct A 
{
  static int x; 
};

int A::x; 

Line 2 declares but does not define A::x, while line 6 defines A::x.
All definitions are declarations, but not all declarations are definitions.

In your program, lines 29-32 are definitions. The definitions are in a header file. Therefore each source file that includes the header file contains the exact same definitions, which is not allowed according to the one definition rule. The one definition rule or ODR essentially says that only one definition of any particular thing can appear in a program. There is of course a lengthy list of exceptions.
https://eel.is/c++draft/basic.def.odr
This is the example code from the book.
"C++ From Control Structures through Objects" by Tony Gaddis.

Tree.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//Tree class
class Tree
{
private:
 static int objectCount;

public:
Tree()
{
  objectCount++;
}

int getObjectCount() const
{
 return objectCount;
}

};


//Definition of the static member variable, written outside of class
int Tree::objectCount =0;

In the next paragraph, the author stated following :

"line22 we have written a definition statement for the objectCount variable, and that the statement is outside the class declaration. This external definition statement causes the variable to be created in memory, and IS REQUIRED."

I tried this example code with a main file and it worked, which I am convinced that the code I wrtoe on original post has a problem but I don't get that my code is wrong because the definitions are defined in the header file(outside of class). Than, why this example code from the book is okay??
because the definitions are defined in the header file


That is the problem. The declaration goes in the header file. The definition has only to be once across all the compilation units.

The code guard doesn't stop the include file being used in multiple compilation units. It only stops multiple inclusion within the same compilation unit.

The same definition across multiple compilation units are not allowed (as you're got by putting the definition in the header file).

The definition of static class variables are often done just above main()

Putting the definition in a header file works if and only if the header file is included in only one compilation unit. if there is only one compilation unit then this will work - until you have more than one then it won't.

If you do put the definition in the header file, then with C++17 use inline as per kbw's post above.

Last edited on
I think you can have your declaration in the header outside the class, but requirement to add the inline keyword, just like for functions.

definition outside header:
inline string Number::thousands="thousands";
Topic archived. No new replies allowed.