C++ static member deconstructor called multiple times

时间:2015-11-12 11:24:30

标签: c++ object constructor static

I have a Properties class which loads some properties from a file. I want to have only one instance of the properties and to be accessible from all classes. Here is what i did in a very Java spirit:

class Properties{
public:
    static Properties getInstance();
    ~Properties();
private:
    Properties();
    static Properties instance;
}

So the Class has a static member of itself which can me accessed from the function getInstance(). I then have various other functions to get the properties from the object. E.g.

Properties::getInstance().getUseDepthInpainting();

The weird thing is that only the first time I try to access a property I get the right value. Other than that I get zero values. I then proceeded to put a print statement in the constructor and one in the deconstructor. While, as expected, the constructor is called only the first time I call getInstance(), the deconstructor gets called every time time the getInstance() is called.. Can someone explain why this is happening, and what is the correct way of doing this?

4 个答案:

答案 0 :(得分:3)

Singleton works on 3 ingredients:

  • private reference
  • private constructor
  • public creational function ("instance", "getInstance" etc.)

The trick goes like this:

  1. call the creational function
  2. the creational function checks if the pointer is null
  3. if the pointer is null - create new instance on it
  4. return the pointer

in your snippet the isntance is not held by a pointer, but is a full-standing object. if you change instance to be from the type Properties* and getInstance() to return Properties* (or Properties&) I guess the problem will be solved

Currently, at the verge of 2016, the correct way to write a singletone is as follows:

class Singleton{

private:
  static std::unique_ptr<Singleton> instance;
  static std::once_flag onceFlag;
  Singleton();

public:
  static Singleton& getInstance(){
    std::call_once(onceFlag,[&]{
       instance = std::unique_ptr<Singleton>(new Singleton());    
    });
    return *instance;
  }

};

答案 1 :(得分:2)

Your getInstance method is returning the properties by value, which means you return a copy of the actual instance. It is this copy that is being destroyed every time it goes out of scope.

The solution is returning a reference to the instance object, by changing the signature of your function to:

static Properties& getInstance();

It is probably even better, if your object is read-only, to make it a const reference so your caller can't go messing about in your Properties object:

static const Properties& getInstance();

答案 2 :(得分:2)

static member deconstructor called multiple times

Nope, the destructor of the static member is only called once.

While, as expected, the constructor is called only the first time I call getInstance(), the deconstructor gets called every time time the getInstance() is called.. Can someone explain why this is happening, and what is the correct way of doing this?

The destructor is called for each copy of instance that are returned by getInstance when they get destroyed. The default constructor is called only once: The other instances are created using the copy-constructor.

It seems that you're attempting to implement the singleton pattern. In that case you should be returning a reference to the instance.

答案 3 :(得分:1)

  

虽然正如预期的那样,构造函数仅在我第一次调用时才被调用   调用getInstance(),每次都会调用解构函数   调用getInstance()。

默认构造函数调用一次。所有其他时间都有复制构造函数的调用。

删除副本并移动构造函数和赋值运算符。

这是一个正确的单身人士:

class Singleton
{
public:
    static Singleton & Instance()
    {
        // Since it's a static variable, if the class has already been created,
        // It won't be created again.
        // And it **is** thread-safe in C++11.

        static Singleton myInstance;

        // Return a reference to our instance.
        return myInstance;
    }

    // delete copy and move constructors and assign operators
    Singleton(Singleton const&) = delete;             // Copy construct
    Singleton(Singleton&&) = delete;                  // Move construct
    Singleton& operator=(Singleton const&) = delete;  // Copy assign
    Singleton& operator=(Singleton &&) = delete;      // Move assign

    // Any other public methods

protected:
    Singleton()
    {
         // Constructor code goes here.
    }

    ~Singleton()
    {
         // Destructor code goes here.
    }

     // And any other protected methods.
}

来自rosettacode