0

I have Commons.h file that contains "general" structures and classes declarations. Among others it contains such class declaration (only static int nInstrument is important, you can ignore the rest):

class Instrument
{
public:

    int Id() {
        return _id;
    }

    int GateId() {
        return _gateId;
    }

    const std::string& const ClassCode() const {
        return _classCode;
    }

    const std::string& const Ticker() const {
        return _ticker;
    }

    Instrument(int gateId_, std::string classCode_, std::string ticker_)
    {
        _gateId = gateId_;
        _classCode = classCode_;
        _ticker = ticker_;
        _id = nInstrument;
        std::cout << "New Instrument created << " << _ticker << " id = " << _id << std::endl;
        ++nInstrument;
    }

private:
    static int nInstrument;
    int _id;
    int _gateId;
    std::string _classCode;
    std::string _ticker;
};

I need to initialize static int nInstrument; with 0. It's easy If I have Commons.cpp file as answered in this question. But I don't ave Commons.cpp file and I don't want to create it just to put one line int Instrument::nInstrument = 0;

I want to double check that C++11 or future standart still doesn't have such feature? So I have to add cpp just to put one initialization line?

Community
  • 1
  • 1
Oleg Vazhnev
  • 23,239
  • 54
  • 171
  • 305
  • c++11 has "constexpr" keyword which can be used to initialize static const members inline – bobah Jan 08 '14 at 13:15
  • 1
    It should also be possible to put the initialization into any compilation unit that uses the header. But creating the cpp is easier to understand for others – user1781290 Jan 08 '14 at 13:16
  • 2
    @EdHeal i typed a question to improve my knoledge :) – Oleg Vazhnev Jan 08 '14 at 13:17
  • You can put that line in any file; it doesn't have to be Commons.cpp. – molbdnilo Jan 08 '14 at 13:17
  • @bobah could you give an example? – Oleg Vazhnev Jan 08 '14 at 13:20
  • @javapowered Aren't all static members initialized to zero by default? – Marian Jan 08 '14 at 13:22
  • The value has to be stored somewhere, which is why you need to define it in a c(pp) file. Putting them in a header would cause them to be defined in every cpp that includes that header. The only exception are templates, which have to be fully defined in a header, you could make a workaround using them. – riv Jan 08 '14 at 13:23
  • @bobah but it looks like OP wants to be able to modify the static at runtime. – juanchopanza Jan 08 '14 at 13:23
  • you can use `#ifdef`s in your header to make it work (and small changes to your build script), but I'd advise against this – user1781290 Jan 08 '14 at 13:24
  • I just want something like `static int nInstrument = 0;`. I can do it in `C#` for example. BTW Not sure if static int is initialized by default to `0` – Oleg Vazhnev Jan 08 '14 at 13:25

3 Answers3

2

If want want to have a static variable into a header only, you may use the following in your class:

static int& nInstrument() { static int s_i = 0; return s_i; }
Jarod42
  • 203,559
  • 14
  • 181
  • 302
1

The C++11 has this kind of feature, but the most common compiler do not support it (yet). I tested that with XCode and VS2013. I got another solution, based on a question I already asked yesterday.

you have to form the attribute into a method:

class Instrument
{
 // your stuff

static int getInstrument()
{
   static int nInstrument=1234;
   return nInstrument;
}

};

This is header only. You can even extend that, look at the answers at: How to change a behavior for all instances of a class in a header only class

Community
  • 1
  • 1
Martin Schlott
  • 4,369
  • 3
  • 25
  • 49
0

You can make a workaround using templates (which allow instantiating static members directly in a header file):

class Instrument
{
  template<class T>
  struct Counter { static int value; };
  int _id;
public:
  Instrument()
    : _id(Counter<int>::value++)
  {}
  int id() { return _id; }
};
int Test::Counter<int>::value = 1;
riv
  • 6,846
  • 2
  • 34
  • 63