单例模式的类成员初始化失败

时间:2014-01-27 18:37:59

标签: c++ class singleton

我正在使用单例模式编写课程。代码如下:

A.H

#include <iostream>

class A {
public:
    static A get_instance();
    static A* get_instance_ptr();
    void init(int i);
    void print_data(void);
private:
    static A* instance_ptr;
    int data;
};

A* A::instance_ptr = NULL;

A* A::get_instance_ptr()
{
    if (NULL == instance_ptr) {
        instance_ptr = new A();
    }
    return instance_ptr;
}

A A::get_instance()
{
    return *get_instance_ptr();
}

void A::init(int i) 
{
    data = i;
    std::cout << "In A::init, data = " << data << std::endl;
}

void A::print_data(void)
{
    std::cout << "In A::print_data, data = " << data << std::endl;
}

main.cpp中:

#include <iostream>
#include "A.h"

int main(int argc, _TCHAR* argv[])
{
    A::get_instance().init(42);
    A::get_instance().print_data();
    return 0;
}

原则是初始化data中的A::init()并将其打印在A::print_data中。但输出是:

In A::init, data = 42
In A::print_data, data = 0

似乎data初始化无效。但是,如果我将main中的初始化更改为:

A::get_instance_ptr()->init(42);

输出符合预期:

In A::init, data = 42
In A::print_data, data = 42

所以问题是,为什么第一次尝试时成员初始化失败了?

1 个答案:

答案 0 :(得分:2)

因为get_instance的返回类型是A而不是正确的A&,所以每次调用它时都会返回“单身”的副本。 init调用对原始对象的副本进行操作,然后print_data对另一个副本进行操作。完成所有操作后,main已成功创建了三个单身人士副本。

可以复制的单身人士并不是真正的单身人士。您应该尽量避免复制(声明私有ctors和赋值运算符,而不是定义它们)。