user3900456
user3900456

Reputation: 2003

Where should static variables be declared

What's the difference between declaring static variables inside a class, in the .h file or in the class definition .cpp file?

Example:

//File.h
class File
{
private:
    const static int number = 10;    
public:
    File();
    ~File();
};

or

//File.cpp

#include "File.h"

const static int number = 10;

File::File()
{
}

File::~File()
{
}

The idea is to use those variables for every instance of File.

Upvotes: 2

Views: 1225

Answers (4)

Werner Henze
Werner Henze

Reputation: 16781

Putting number into the class declaration makes it a member of the class. So everyone who is including the header file and has the access rights can access the member.

In your second case the variable number is only visible in the cpp file where you define it, not in other cpp files.

If like in your case the number member is made private and the implementation of the class is all in one cpp file only and not scattered over multiples cpp files, then there is no difference for you in both variants. Then it is just a matter of style or preference. If the cpp file for this class is very big and you splitted it up into multiple cpp files, and at least two of them need access to number, then it would be better to have the member in the class than to have one variable in each file (each having the same local name and value, but different identity).

BTW, when putting it into the cpp file you should not write static const int number = 10; but put it into an anonymous namespace namespace { constexpr int number = 10; } (SF.22 in Core Guidelines). Please note that constexpr also has some advantages over const.

Upvotes: 1

JVApen
JVApen

Reputation: 11317

The answer to your question depends on the c++ standard you are using. If you are using an old standard as C++11 or C++14 (Ignoring the acciant C++98/03), you have to put the instantiation of the variable in the ccp:

//File.h
class File
{
private:
    const static int number;    
public:
    File() = default;
    ~File() = default;
};

//File.cpp   
#include "File.h"

const int File::number = 10;

This because ODR, the one definition rule. It states that every variable or function can only exist in a single compilation unit. This unless declared inline, in which case all compilation units should have the same definition. (No diagnostic required if violated)

From c++17 (and the upcoming C++20, which is being formalized), variables can, like functions before, be declared inline, this allows you to write the following:

//File.h
class File
{
private:
    inline const static int number = 10;    
public:
    File() = default;
    ~File() = default;
};

The big difference here is that when you change number, you need to recompile all compilation units that include the header, this to reduce typing.The additional advantage is that your compiler can use the information to optimize the code using it, as it can inline the variable. Also the users of your class, like yourself debugging in a few months, can easer see what's going on.

In this specific case, we are looking at an int, so, I would even go a step further and declare the variable as constexpr:

//File.h
class File
{
private:
    constexpr static int number = 10;    
public:
    File() = default;
    ~File() = default;
};

Constexpr variables are implicit const and inline, reducing some typing. They can also be used in constexpr context, as template argument ... And assuming you wrote a calculation (1+2+3+4), if forces your compiler to calculate and store the calculated value even in debug builds.

A side note, given in comments by Tony, you can as well put your code in an unnamed namespace in the cpp, also this is possible with constexpr. This makes a lot of sense if you don't expose any usage of this variable to other compilation units. (Private, no friends and no usage in inline functions)

 namespace { const int number = 10; }
 namespace { constexpr int number = 10; }

Upvotes: 3

restless_soul469
restless_soul469

Reputation: 137

From cpp forum reference (more).

If a header file is included in multiple cpp files then initialising (and hence defining it) a variable in it will break the one definition rule. The variable must be only declared in the header and then defined (and initialized) in a single .cpp file.

To summarize it's not a good idea to initialize a variable in header file. Few more links if you need. st1 , st2

Upvotes: 1

Some programmer dude
Some programmer dude

Reputation: 409482

You declare the variables inside the class definition, then you define them in a source file.

But you need to use the proper scope when defining the variable, just like you use for member functions:

const int File::number = 10;
//        ^^^^^^
// Note scope here

Upvotes: 3

Related Questions