Static Constructors in C++? I Need to Initialize Private Static Objects

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

};

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;
};

Can I make sure a static constructor has finished before I create an instance?

Here's a good link on the nuances of before-field-init, but indeed: adding an explicit static constructor should force the runtime's hand here. Note that the while (list == null) {} will not work, because that also forces the runtime's hand - you should never be able to observe the lies that the runtime tells you, basically.

In the example shown, it won't matter. You will never see a null for listLock or list. If you really really demand that they run before constructors:

private static List<string> list;
private static object listLock;
static Foo() {
list = new List<string>();
listLock = new object();
}

But note that this is not really necessary and may negatively impact your code, especially with the new JIT in .NET Core 3 that can treat static readonly fields with extra voodoo if they are initialized neatly (I know it can do this if they are inline field initializers without an explicit static constructor; I don't know if it can do this if they are assigned by an explicit static constructor).

What is the advantage of initializing static variable in a static constructor instead of direct assignment of value

they will be compiled in to same thing. so no difference,

That's not private constructor. that's static constructor

A static constructor is used to initialize any static data, or to perform a particular action that needs to be performed once only. It is called automatically before the first instance is created or any static members are referenced

I use static constructor when by directly assigning value, the line becomes too long (that's opinion based) or when I need multiple lines to initialize a value.

Initializing static member variables in constructors error in c++

You have to explicitly define count, as there is no definition of count. You have just declared the static variable, you have not defined it.

class MyObject
{ private:
static int count;
MyObject()
{
count=0;
}
};
int MyObject::count = 0; //Explicit definition of static variables.

Is it possible to initialize static fields within a static function?

When you declare static variables, you also have to define them. In your cpp file, after the Foo declaration, add this line:

SomeType Foo::myField;

Then, your init function should work.


Also note that you can initialize it directly by defining it like this:

SomeOtherType sot;
SomeType Foo::myField = sot.someNonStaticFunction();

or :

SomeType Foo::myField = SomeOtherType().someNonStaticFunction();


Related Topics



Leave a reply



Submit