我正在使用单例模式编写课程。代码如下:
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
所以问题是,为什么第一次尝试时成员初始化失败了?
答案 0 :(得分:2)
因为get_instance
的返回类型是A
而不是正确的A&
,所以每次调用它时都会返回“单身”的副本。 init
调用对原始对象的副本进行操作,然后print_data
对另一个副本进行操作。完成所有操作后,main
已成功创建了三个单身人士副本。
可以复制的单身人士并不是真正的单身人士。您应该尽量避免复制(声明私有ctors和赋值运算符,而不是定义它们)。