Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should static variables be declared [duplicate]

Tags:

c++

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.

like image 656
user3900456 Avatar asked Jun 15 '26 07:06

user3900456


2 Answers

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
like image 82
Some programmer dude Avatar answered Jun 16 '26 19:06

Some programmer dude


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; }
like image 43
JVApen Avatar answered Jun 16 '26 20:06

JVApen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!