192

I want to have a class with a private static data member (a vector that contains all the characters a-z). In java or C#, I can just make a "static constructor" that will run before I make any instances of the class, and sets up the static data members of the class. It only gets run once (as the variables are read only and only need to be set once) and since it's a function of the class it can access its private members. I could add code in the constructor that checks to see if the vector is initialized, and initialize it if it's not, but that introduces many necessary checks and doesn't seem like the optimal solution to the problem.

The thought occurs to me that since the variables will be read only, they can just be public static const, so I can set them once outside the class, but once again, it seems sort of like an ugly hack.

Is it possible to have private static data members in a class if I don't want to initialize them in the instance constructor?

peterh
  • 11,875
  • 18
  • 85
  • 108
Gordon Gustafson
  • 40,133
  • 25
  • 115
  • 157

23 Answers23

191

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

};
Daniel Earwicker
  • 114,894
  • 38
  • 205
  • 284
  • 13
    thanks! though that's very annoying to have to do all that. One of the many "mistakes" C# and java learned from. – Gordon Gustafson Jul 28 '09 at 22:59
  • 119
    Yes. I always point out to people that if C++ hadn't made all those "mistakes" then other languages would have to make them. C++ covering so much ground, even making mistakes, has been great for the languages that followed it. – quark Jul 28 '09 at 23:02
  • 12
    Just one little nuance, as constructors come into play no one guarantees when the constructor for static object executes. A well-known much safer approach is class Elsewhere { StaticStuff& get_staticStuff() { static StaticStuff staticStuff; // constructor runs once, when someone first needs it return staticStuff; } }; I wonder if static constructors in C# and Java can provide the same guarantee as the code above... – Oleg Zhylin Jul 28 '09 at 23:31
  • 13
    @Oleg: Yes they do. The standard gurantees that the constructors for all non local variables are executed before main is entered. It also gurantees that within a compilation unit the order of construction is well defined and the same order as declaration within the compilation unit. Unfortunately they do not define the order across multiple compilation units. – Martin York Jul 29 '09 at 02:25
  • 1
    @Oleg: further to Martin's answer about order of construction in C++, the answer for C# is that code is dynamically loaded on demand, and statics are initialized on demand, and this is a thread-safe facility, so statics effectively work like thread-safe lazy singletons (with a built-in correct implementation of double-checked locking). Hence order-of-init problems can still occur where there are circular references, but they are unusual. Not sure how much this is true in Java. – Daniel Earwicker Jul 29 '09 at 07:07
  • 2
    As for language wars, it shouldn't be a surprise that Java has some nice things that C++ doesn't, as they were created a decade apart, and then C# came about five years after Java. This is surely not controversial. Also C++ and the other two languages don't even serve the same purpose, really. – Daniel Earwicker Jul 29 '09 at 07:08
  • 13
    This is actually a case where `friend` makes a lot of sense so that class `Elsewhere` may easily access `StaticStuff`’s internals (without breaking encapsulation in any dangerous way, I might add). – Konrad Rudolph Jan 26 '10 at 20:38
  • @Loki: Can you please specify which language standard you are referring to. It's not clear which of his arguments you're refuting. – drifter Apr 15 '12 at 14:50
  • @drifter: My comment above is pointed at 'Oleg' comments (hence the @ Oleg). On the points I outlined above it has been like this since the earliest version of the standard I have read. But since the post was made in 2009 Lets go with [N2960](http://www.open-std.org/Jtc1/sc22/wg21/docs/papers/2009/n2960.pdf) but now you should be reading the latest: http://stackoverflow.com/a/4653479/14065 – Martin York Apr 15 '12 at 15:23
  • @Loki: Oleg made two statements you could have been responding to: "...no one guarantees when the constructor for static object executes," and "I wonder if static constructors in C# and Java can provide the same guarantee..." Thank you for pointing out that the C++ standard does indeed guarantee this. – drifter Apr 16 '12 at 13:30
  • Wow, this is awesome! I wonder, why not make StaticStuff *inheriting*`std::vector` instead of using composition? This would save a lot of typing later, and makes a lot of sense since you actually wanted your "static stuff" to **be** a vector of char, and just use this as a workaround for a limitation of C++. Any good reason for using composition in this case? – Boris Dalstein Oct 03 '13 at 08:17
  • Inheriting a type that is not designed to be inherited from is potentially problematic in C++, because such types don't have a virtual destructor. So `std::vector *p = new StaticStuff` would be possible according to the type system, but `delete p` would caused Undefined Behaviour. If `std::vector` had a protected destructor, `delete p` would be blocked by the type system, but then we'd be forced to use `std::vector` only as a base class. If `std::vector` had a virtual destructor, it would be a tad more costly at runtime (which is antithetical to the C++ approach). – Daniel Earwicker Oct 03 '13 at 12:14
  • IFF you only use `StaticStuff` as above (i.e. not polymorphically referenced) then it is technically okay to inherit `std::vector`, but in reality you probably don't want to expose all the public features of `std::vector`. You almost certainly want only the `const` features, so the shared vector doesn't get modified accidentally. And you may be able to cut the required interface down further even than that (always a good idea for interfaces to be minimal), which is most clearly done via composition. – Daniel Earwicker Oct 03 '13 at 12:18
86

Well you can have

class MyClass
{
    public:
        static vector<char> a;

        static class _init
        {
          public:
            _init() { for(char i='a'; i<='z'; i++) a.push_back(i); }
        } _initializer;
};

Don't forget (in the .cpp) this:

vector<char> MyClass::a;
MyClass::_init MyClass::_initializer;

The program will still link without the second line, but the initializer will not be executed.

EFraim
  • 12,811
  • 4
  • 46
  • 62
  • +1 (didn't try it out) But: When is ctor _init._init() called? Before or after the ctor of MyClass when I have a static MyClass object? I guess you can't tell... – ur. Jan 28 '10 at 16:18
  • 3
    hello, where can I find more about this "initializer" magic? – Karel Bílek Apr 30 '10 at 22:10
  • Shouldn't it be `MyClass::a.push_back(i)` instead of `a.push_back(i)` ? – Neel Basu Apr 26 '11 at 06:48
  • 4
    @ur.: `_initializer` is a subobject of `MyClass`. Subobjects are initialised in this order: virtual base class subobjects, in depth-first, left-to-right order (but only initialising each distinct subobject once); then plain base class subobjects, in depth-first, left-to-right order; then member subobjects in order of declaration. So it's safe to use EFraim's strategy, provided that code in `_initialiser` only refers to members declared before it. – j_random_hacker Nov 29 '11 at 02:52
  • FYI: I added the needed static definitions, plus made _init() private, and tested that the code still works. – Blaisorblade Jan 29 '12 at 11:02
  • Tried at and it wouldn't work without declaring the _init constructor as public (or declaring _init as struct) on Visual C++ 2010. Should your code work as such? – OregonGhost Dec 11 '12 at 09:15
  • @Blaisorblade: Well I've verified with Studio 11 and it does not work with private static constructor (does not compile) - modifying the code to compile with standard C++. – EFraim Dec 12 '12 at 13:38
49

C++11 update

Since C++11, you can simply use lambda expressions to initialize static class members. You don't need to use any helper classes or workarounds anymore.

Header file:

class MyClass {
    static const vector<char> letters;
};

Source file:

// Initialize MyClass::letters with all letters from 'a' to 'z'.
const vector<char> MyClass::letters = [] {
    vector<char> letters;
    for (char c = 'a'; c <= 'z'; c++)
        letters.push_back(c);
    return letters;
}();

Note about static initialization order:

This approach also works if multiple static class members must be initialized in some specific order. Since static members are always initialized in the exact same order as defined within the source file, you just simply have to make sure that you write your initializations within the source file in the correct order.

emkey08
  • 5,059
  • 3
  • 33
  • 34
  • interesting solution. in this case if i throw an exception who can catch it? – rafi wiener Jan 08 '18 at 08:10
  • 7
    Static program initialization code must **never** throw any exceptions, or the program will crash. You must wrap the initializer logic into a `try catch` block if exceptions might be thrown. – emkey08 Jan 20 '18 at 22:00
21

In the .h file:

class MyClass {
private:
    static int myValue;
};

In the .cpp file:

#include "myclass.h"

int MyClass::myValue = 0;
Ant
  • 4,890
  • 1
  • 31
  • 42
  • 5
    This works fine for individual static members (regardless of type). The deficiency in comparison to static constructors is that you can't impose an *order* between the various static members. If you need to do that, see Earwicker's answer. – quark Jul 28 '09 at 22:36
  • I'm doing exactly that, but it still doesn't compile. And it says this is the problem area (in the constructor, not the header) – Flotolk Oct 12 '15 at 15:14
17

Here is another approach similar to Daniel Earwicker's, also using Konrad Rudolph's friend class suggestion. Here we use an inner private friend utility class to initialize the static members of your main class. For example:

Header file:

class ToBeInitialized
{
    // Inner friend utility class to initialize whatever you need

    class Initializer
    {
    public:
        Initializer();
    };

    friend class Initializer;

    // Static member variables of ToBeInitialized class

    static const int numberOfFloats;
    static float *theFloats;

    // Static instance of Initializer
    //   When this is created, its constructor initializes
    //   the ToBeInitialized class' static variables

    static Initializer initializer;
};

Implementation file:

// Normal static scalar initializer
const int ToBeInitialized::numberOfFloats = 17;

// Constructor of Initializer class.
//    Here is where you can initialize any static members
//    of the enclosing ToBeInitialized class since this inner
//    class is a friend of it.

ToBeInitialized::Initializer::Initializer()
{
    ToBeInitialized::theFloats =
        (float *)malloc(ToBeInitialized::numberOfFloats * sizeof(float));

    for (int i = 0; i < ToBeInitialized::numberOfFloats; ++i)
        ToBeInitialized::theFloats[i] = calculateSomeFancyValue(i);
}

This approach has the advantage of completely hiding the Initializer class from the outside world, keeping everything contained within the class to be initialized.

Douglas Mandell
  • 179
  • 1
  • 2
  • 2
    Also, you have to make sure that `ToBeInitialized::Initializer::Initializer()` gets called, so you need to add `ToBeInitialized::Initializer ToBeInitialized::initializer;` to the implementation file. I took some things from your idea and from EFraim's idea, and it works exactly as I need it to and looks clean. Thanks, man. – Andrew Larsson Feb 09 '14 at 10:19
12

Test::StaticTest() is called exactly once during global static initialization.

Caller only has to add one line to the function that is to be their static constructor.

static_constructor<&Test::StaticTest>::c; forces initialization of c during global static initialization.

template<void(*ctor)()>
struct static_constructor
{
    struct constructor { constructor() { ctor(); } };
    static constructor c;
};

template<void(*ctor)()>
typename static_constructor<ctor>::constructor static_constructor<ctor>::c;

/////////////////////////////

struct Test
{
    static int number;

    static void StaticTest()
    {
        static_constructor<&Test::StaticTest>::c;

        number = 123;
        cout << "static ctor" << endl;
    }
};

int Test::number;

int main(int argc, char *argv[])
{
    cout << Test::number << endl;
    return 0;
}
CuriousGeorge
  • 7,120
  • 6
  • 42
  • 74
9

No need for an init() function, std::vector can be created from a range:

// h file:
class MyClass {
    static std::vector<char> alphabet;
// ...
};

// cpp file:
#include <boost/range.hpp>
static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
std::vector<char> MyClass::alphabet( boost::begin( ::alphabet ), boost::end( ::alphabet ) );

Note, however, that statics of class type cause trouble in libraries, so they should be avoided there.

C++11 Update

As of C++11, you can do this instead:

// cpp file:
std::vector<char> MyClass::alphabet = { 'a', 'b', 'c', ..., 'z' };

It's semantically equivalent to the C++98 solution in the original answer, but you can't use a string literal on the right-hand-side, so it's not completely superior. However, if you have a vector of any other type than char, wchar_t, char16_t or char32_t (arrays of which can be written as string literals), the C++11 version will strictly remove boilerplate code without introducing other syntax, compared to the C++98 version.

Marc Mutz - mmutz
  • 24,485
  • 12
  • 80
  • 90
  • I like it. Though if only we could do it in one line without the now usless alphabet. – Martin York Aug 01 '09 at 09:04
  • For causing problems with libraries, does it matter if the static class is private or public? Additionally, does it matter if the library is static(.a) or dynamic(.so)? – Zachary Kraus Mar 19 '15 at 06:15
  • @ZacharyKraus: what's a public/private _class_? And no, while the problems are different, but overlapping, it doesn't matter whether the library is linked statically or dynamically. – Marc Mutz - mmutz Mar 19 '15 at 07:49
  • @MarcMutz-mmutz Sorry about using public/private class which is not correct C++ terminology. What I was referring to is the solution by EFraim above. In my version though, I made the static class member private. I was trying to understand if having a static class member as public or private makes a difference in library development and usability. My gut tells me it should not effect the library because users will never have access to either the static class member or the object its building, but I would love to get some guru's wisdom on this topic. – Zachary Kraus Mar 19 '15 at 17:12
  • @ZacharyKraus: The main problem with statics that require dynamic initialisation ([basic.start.init]/2) is that they run code. In libraries, it could be that the library code has already been unloaded when the destructors are run. If you want to hear more, I suggest to post a question about it. – Marc Mutz - mmutz Mar 22 '15 at 20:13
  • Thanks Ill post a question on this since I am using a descent amount of singletons in a dynamic library and some other static structures as well. – Zachary Kraus Mar 23 '15 at 02:28
7

The concept of static constructors was introduced in Java after they learned from the problems in C++. So we have no direct equivalent.

The best solution is to use POD types that can be initialised explicitly.
Or make your static members a specific type that has its own constructor that will initialize it correctly.

//header

class A
{
    // Make sure this is private so that nobody can missues the fact that
    // you are overriding std::vector. Just doing it here as a quicky example
    // don't take it as a recomendation for deriving from vector.
    class MyInitedVar: public std::vector<char>
    {
        public:
        MyInitedVar()
        {
           // Pre-Initialize the vector.
           for(char c = 'a';c <= 'z';++c)
           {
               push_back(c);
           }
        }
    };
    static int          count;
    static MyInitedVar  var1;

};


//source
int            A::count = 0;
A::MyInitedVar A::var1;
Martin York
  • 257,169
  • 86
  • 333
  • 562
4

I guess Simple solution to this will be:

    //X.h
    #pragma once
    class X
    {
    public:
            X(void);
            ~X(void);
    private:
            static bool IsInit;
            static bool Init();
    };

    //X.cpp
    #include "X.h"
    #include <iostream>

    X::X(void)
    {
    }


    X::~X(void)
    {
    }

    bool X::IsInit(Init());
    bool X::Init()
    {
            std::cout<< "ddddd";
            return true;
    }

    // main.cpp
    #include "X.h"
    int main ()
    {
            return 0;
    }
Shubham
  • 172
  • 8
4

When trying to compile and use class Elsewhere (from Earwicker's answer) I get:

error LNK2001: unresolved external symbol "private: static class StaticStuff Elsewhere::staticStuff" (?staticStuff@Elsewhere@@0VStaticStuff@@A)

It seems is not possible to initialize static attributes of non-integer types without putting some code outside the class definition (CPP).

To make that compile you can use "a static method with a static local variable inside" instead. Something like this:

class Elsewhere
{
public:
    static StaticStuff& GetStaticStuff()
    {
        static StaticStuff staticStuff; // constructor runs once, single instance
        return staticStuff;
    }
};

And you may also pass arguments to the constructor or initialize it with specific values, it is very flexible, powerfull and easy to implement... the only thing is you have a static method containing a static variable, not a static attribute... syntaxis changes a bit, but still useful. Hope this is useful for someone,

Hugo González Castro.

Community
  • 1
  • 1
  • Though be careful if using threads. I believe in GCC the construction of static locals is protected against concurrent execution, but in Visual C++ it is not. – Daniel Earwicker Oct 12 '11 at 13:56
  • 1
    From C++11 onwards, and in POSIX, it *has* to be thread-safe. – Marc Mutz - mmutz Mar 23 '15 at 09:51
  • I quite liked two other solutions above ([this](http://stackoverflow.com/a/18434215/156328) and [this](http://stackoverflow.com/a/4742211/156328)), but yours is the only one that ensures initialization of statics in the order they're needed across libraries. I just have a private static Instance method like yours above, and wrap access to other values in public static accessors that use that Instance method instead of direct references. Thanks. – FlintZA Feb 09 '16 at 05:21
2

Wow, I can't believe no one mentioned the most obvious answer, and one that most closely mimics C#'s static-constructor behavior, i.e. it doesn't get called until the first object of that type is created.

std::call_once() is available in C++11; if you can't use that, it can be done with a static boolean class-variable, and a compare-and-exchange atomic-operation. In your constructor, see if you can atomically change the class-static flag from false to true, and if so, you can run the static-construction code.

For extra credit, make it a 3-way flag instead of a boolean, i.e. not run, running, and done running. Then all other instances of that class can spin-lock until the instance running the static-constructor has finished (i.e. issue a memory-fence, then set the state to "done running"). Your spin-lock should execute the processor's "pause" instruction, double the wait each time up until a threshold, etc. — pretty standard spin-locking technique.

In the absence of C++11, this should get you started.

Here's some pseudocode to guide you. Put this in your class definition:

enum EStaticConstructor { kNotRun, kRunning, kDone };
static volatile EStaticConstructor sm_eClass = kNotRun;

And this in your constructor:

while (sm_eClass == kNotRun)
{
    if (atomic_compare_exchange_weak(&sm_eClass, kNotRun, kRunning))
    {
        /* Perform static initialization here. */

        atomic_thread_fence(memory_order_release);
        sm_eClass = kDone;
    }
}
while (sm_eClass != kDone)
    atomic_pause();
ulatekh
  • 1,311
  • 1
  • 14
  • 19
1

Here's another method, where the vector is private to the file that contains the implementation by using an anonymous namespace. It's useful for things like lookup tables that are private to the implementation:

#include <iostream>
#include <vector>
using namespace std;

namespace {
  vector<int> vec;

  struct I { I() {
    vec.push_back(1);
    vec.push_back(3);
    vec.push_back(5);
  }} i;
}

int main() {

  vector<int>::const_iterator end = vec.end();
  for (vector<int>::const_iterator i = vec.begin();
       i != end; ++i) {
    cout << *i << endl;
  }

  return 0;
}
Jim Hunziker
  • 14,111
  • 8
  • 58
  • 64
  • Though you might want to name `I` and `i` something a little more obscure so you don't accidentally use them somewhere lower in the file. – Jim Hunziker Jul 31 '12 at 16:21
  • 1
    To be honest, it's hard to see why anyone would want to use private static members rather than anonmymous namespaces in implementation files. – Jim Hunziker Jul 31 '12 at 16:25
1

It certainly doesn't need to be as complicated as the currently accepted answer (by Daniel Earwicker). The class is superfluous. There's no need for a language war in this case.

.hpp file:

vector<char> const & letters();

.cpp file:

vector<char> const & letters()
{
  static vector<char> v = {'a', 'b', 'c', ...};
  return v;
}
AndyJost
  • 1,085
  • 1
  • 10
  • 18
1

GCC offers

__attribute__((constructor))

https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html

Tag a static method with this attribute and it will run on module load, before main().

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
jws
  • 2,171
  • 19
  • 30
1

Just solved same trick. I had to specify definition of a single static member for Singleton. But make things more complicated - I have decided that I do not want to call ctor of RandClass() unless I am gonna use it... that is why I did not want to initialize singleton globally in my code. Also I've added simple interface in my case.

Here is the final code:

I simplified code and use rand() function and its single seed initialzer srand()

interface IRandClass
{
 public:
    virtual int GetRandom() = 0;
};

class RandClassSingleton
{
private:
  class RandClass : public IRandClass
  {
    public:
      RandClass()
      {
        srand(GetTickCount());
      };

     virtual int GetRandom(){return rand();};
  };

  RandClassSingleton(){};
  RandClassSingleton(const RandClassSingleton&);

  // static RandClass m_Instance;

  // If you declare m_Instance here you need to place
  // definition for this static object somewhere in your cpp code as
  // RandClassSingleton::RandClass RandClassSingleton::m_Instance;

  public:

  static RandClass& GetInstance()
  {
      // Much better to instantiate m_Instance here (inside of static function).
      // Instantiated only if this function is called.

      static RandClass m_Instance;
      return m_Instance;
  };
};

main()
{
    // Late binding. Calling RandClass ctor only now
    IRandClass *p = &RandClassSingleton::GetInstance();
    int randValue = p->GetRandom();
}
abc()
{
    IRandClass *same_p = &RandClassSingleton::GetInstance();
}
adspx5
  • 731
  • 7
  • 16
1

Here's my variant of EFraim's solution; the difference is that, thanks to implicit template instantiation, the static constructor is only called if instances of the class are created, and that no definition in the .cpp file is needed (thanks to template instantiation magic).

In the .h file, you have:

template <typename Aux> class _MyClass
{
    public:
        static vector<char> a;
        _MyClass() {
            (void) _initializer; //Reference the static member to ensure that it is instantiated and its initializer is called.
        }
    private:
        static struct _init
        {
            _init() { for(char i='a'; i<='z'; i++) a.push_back(i); }
        } _initializer;

};
typedef _MyClass<void> MyClass;

template <typename Aux> vector<char> _MyClass<Aux>::a;
template <typename Aux> typename _MyClass<Aux>::_init _MyClass<Aux>::_initializer;

In the .cpp file, you can have:

void foobar() {
    MyClass foo; // [1]

    for (vector<char>::iterator it = MyClass::a.begin(); it < MyClass::a.end(); ++it) {
        cout << *it;
    }
    cout << endl;
}

Note that MyClass::a is initialized only if line [1] is there, because that calls (and requires instantiation of) the constructor, which then requires instantiation of _initializer.

Blaisorblade
  • 6,438
  • 1
  • 43
  • 76
0

You define static member variables similarly to the way you define member methods.

foo.h

class Foo
{
public:
    void bar();
private:
    static int count;
};

foo.cpp

#include "foo.h"

void Foo::bar()
{
    // method definition
}

int Foo::count = 0;
Nick Lewis
  • 4,150
  • 1
  • 21
  • 22
0

To initialize a static variable, you just do so inside of a source file. For example:

//Foo.h
class Foo
{
 private:
  static int hello;
};


//Foo.cpp
int Foo::hello = 1;
Cristián Romo
  • 9,814
  • 12
  • 50
  • 50
0

How about creating a template to mimic the behavior of C#.

template<class T> class StaticConstructor
{
    bool m_StaticsInitialised = false;

public:
    typedef void (*StaticCallback)(void);

    StaticConstructor(StaticCallback callback)
    {
        if (m_StaticsInitialised)
            return;

        callback();

        m_StaticsInitialised = true;
    }
}

template<class T> bool StaticConstructor<T>::m_StaticsInitialised;

class Test : public StaticConstructor<Test>
{
    static std::vector<char> letters_;

    static void _Test()
    {
        for (char c = 'a'; c <= 'z'; c++)
            letters_.push_back(c);
    }

public:
    Test() : StaticConstructor<Test>(&_Test)
    {
        // non static stuff
    };
};
karmasponge
  • 1,169
  • 2
  • 12
  • 26
0

A static constructor can be emulated by using a friend class or nested class as below.

class ClassStatic{
private:
    static char *str;
public:
    char* get_str() { return str; }
    void set_str(char *s) { str = s; }
    // A nested class, which used as static constructor
    static class ClassInit{
    public:
        ClassInit(int size){ 
            // Static constructor definition
            str = new char[size];
            str = "How are you?";
        }
    } initializer;
};

// Static variable creation
char* ClassStatic::str; 
// Static constructor call
ClassStatic::ClassInit ClassStatic::initializer(20);

int main() {
    ClassStatic a;
    ClassStatic b;
    std::cout << "String in a: " << a.get_str() << std::endl;
    std::cout << "String in b: " << b.get_str() << std::endl;
    a.set_str("I am fine");
    std::cout << "String in a: " << a.get_str() << std::endl;
    std::cout << "String in b: " << b.get_str() << std::endl;
    std::cin.ignore();
}

Output:

String in a: How are you?
String in b: How are you?
String in a: I am fine
String in b: I am fine
Jobin
  • 6,506
  • 5
  • 24
  • 26
  • Why are you `new`ing a char array only to immediately leak the pointer and overwrite it!? – Eric Nov 12 '16 at 01:43
0

For simple cases like here a static variable wrapped inside a static member function is nearly as good. It's simple and will usually be optimized away by compilers. This does not solve initialization order problem for complex objects though.

#include <iostream>

class MyClass 
{

    static const char * const letters(void){
        static const char * const var = "abcdefghijklmnopqrstuvwxyz";
        return var;
    }

    public:
        void show(){
            std::cout << letters() << "\n";
        }
};


int main(){
    MyClass c;
    c.show();
}
kriss
  • 23,497
  • 17
  • 97
  • 116
0

Is this a solution?

class Foo
{
public:
    size_t count;
    Foo()
    {
        static size_t count = 0;
        this->count = count += 1;
    }
};
McDowell
  • 107,573
  • 31
  • 204
  • 267
BSalita
  • 8,420
  • 10
  • 51
  • 68
-1

I use this technique to init static stuff : In the .cpp file :

struct InitMe {
    InitMe(){
        // do all the static stuff you want here
    }
} initMe;

Because it's in a compilation unit, the variable initMe will have a program lifetime. The constructor will be initialized before main(), and the destructor, if any, will be called before program termination. Like all static stuff, there's no guarantee on the order it will be executed, but in a single .cpp file, there's a guarantee that static stuff will be initialized in order they appear in the file.