How to Initialize Private Static Members in C++

How to initialize private static members in C++?

The class declaration should be in the header file (Or in the source file if not shared).

File: foo.h

class foo
{
private:
static int i;
};

But the initialization should be in source file.

File: foo.cpp

int foo::i = 0;

If the initialization is in the header file then each file that includes the header file will have a definition of the static member. Thus during the link phase you will get linker errors as the code to initialize the variable will be defined in multiple source files.
The initialisation of the static int i must be done outside of any function.

Note: Matt Curtis: points out that C++ allows the simplification of the above if the static member variable is of const integer type (bool, char, char8_t [since C++20], char16_t, char32_t, wchar_t, short, int, long, long long, or any implementation-defined extended integer types, including any signed, unsigned, and cv-qualified variants.). You can then declare and initialize the member variable directly inside the class declaration in the header file:

class foo
{
private:
static int const i = 42;
};

How to declare and initialize a static member in a class? [duplicate]

One can definitely have class static members which are not CV-qualified (non const and not volatile). It is just that one should not initialize them (give them value) when one declare them inside the class, based on current ISO C++ regulations. In Comparison, it is OK to do so for non static data members(regardless of CV-qualification) Since C++11.

Because static data members do not belong to any object, with the right access they can be assigned (and if they are not constant, they can be manipulated) outside of the class(keeping in mind the right scope operator). Also regardless of public/private declaration and CV-qualification, static data members can be initialized outside their class.

So one way for initializing static data members, is to do so in the same block-scope/namespace where their classes(outer class in case of sub-classes) are situated, but not inside any class scope.

For example:

class Graph {
public:
class Node {
public:
static int maxNumberOfNeighbors;
.
.
.
};
.
.
.
};

int Graph::Node::maxNumberOfNeighbors = 4;
//also int Graph::Node::maxNumberOfNeighbors(4);


Good luck!

Static member of class with private constructor

It's not only possible, it's (almost) required to do so.

Starting from C++17, you can declare any static variable as inline, and initialize it in class body:

class Double {
private:
inline static int fuzzyComparePrecision_ = 0;
};

Before C++17, every* static class member requires an out-of-class definition.

It can (and usually should) be combined with initialization, to avoid dealing with uninitialized variables.

You have to provide the following (in cpp file):

int Utilities::Double::fuzzyComparePrecision_;

But you can also extend it with initialization:

int Utilities::Double::fuzzyComparePrecision_ = 0;

*There are exceptions - const static members can be initialized in class body with another constant expression.

Initializing private static variable in class

Initialize numEmployees outside of the class as

Employee::numEmployees = 0

and declare it a public member in the class as

static int numEmployees;

You can also declare it private without intialization, as a static member is assigned zero by default.

Private static class members

Yes, it does mean something. Consider the following example, which throws a compiler error, because the member is private. Being able to initialize a private variable is not the same as being able to change it from any context.

class Something
{
private:
static int s_nValue;
};

int Something::s_nValue = 1;

int main(){
Something::s_nValue = 2; // Compiler error here.
}

Initialize a template class private static variable in C++

pv_mem_ is defined as follows

constexpr static std::array<fruitGroup, sizeof...(TotalFruits)> pv_mem_ 
{
fruitGroup{TotalFruits, &FruitFunction<TotalFruits>}...
};

which uses & to take the address of FruitFunction<TotalFruits>, but since FruitFunction is only declared and not defined, it will generate an undefined reference error at runtime.

Adding the definition for the template function FruitFunction will solve the problem in C++17

template <FRUIT T>
void FruitFunction() { /* */ }

In C++11, constexpr static member variables still need to be defined outside the class, so you also need to add

template <FRUIT...TotalFruits>
constexpr std::array<
typename TestClass<TotalFruits...>::fruitGroup,
sizeof...(TotalFruits)> TestClass<TotalFruits...>::pv_mem_;

Demo

Access to private static function during static member initialization

Because the initialization of a static data member is considered part of the characterization of the class even though the static data member is defined at namespace scope (outside the class definition).

From the standard, class.static.data#note-1:

[Note 1: The initializer in the definition of a static data member is
in the scope of its class ([basic.scope.class]). — end note]

[Example 1:

class process {
static process* run_chain;
static process* running;
};

process* process::running = get_main();
process* process::run_chain = running;

The definition of the static data member run_­chain of class process
inhabits the global scope; the notation process​::​run_­chain
indicates that the member run_­chain is a member of class process and
in the scope of class process. In the static data member definition,
the initializer expression refers to the static data member running of
class process. — end example]

Initializing a private static member variable in the cpp file. error: member is private

The error isn't about the initialization. It just points to the initialization as the point where s_nNextID comes from.

The real error is on line 15, where you access s_nNextID from a normal global function, because you forgot the IDGenerator:: in the definition head of GetNextID.

static constructors in C++? I need to initialize private static objects

To get the equivalent of a static constructor, you need to write a separate ordinary class to hold the static data and then make a static instance of that ordinary class.

class StaticStuff
{
std::vector<char> letters_;

public:
StaticStuff()
{
for (char c = 'a'; c <= 'z'; c++)
letters_.push_back(c);
}

// provide some way to get at letters_
};

class Elsewhere
{
static StaticStuff staticStuff; // constructor runs once, single instance

};


Related Topics



Leave a reply



Submit