创建一个为派生类实现单例的基类

时间:2013-12-19 00:28:50

标签: c++ inheritance singleton

所以,在你向我开枪告诉我这是一件非常糟糕的事情之前,我只是想表明我想知道这只是为了好奇和可能的代码减少。我想有一个基类来实现派生类的单例。但是,这样做会导致派生类丢失数据。如何根据派生类获取基类来实现单例。例如:

class Application{
public:
/**
 * @brief instance: C++11 [If control enters the declaration concurrently while the     variable is being initialized,
 *the concurrent execution shall wait for completion of the initialization.—§6.7 [stmt.dcl] p4]
 * @return handle to application
 */
static Application& instance(){
    static Application s_Application;
    return s_Application;
}

void setName(std::string Name){
    AppName=Name;
}

std::string getName(){
    return AppName;
}
virtual ~Application(){ }

private:
Application(){}
std::string AppName;
};

现在我创建一个继承自Application的派生类:

class Test:public Application{
    public:
    void printer(std::string test){
        std::cout<<"test\n";
    }
};


int main(int argc, char *argv[]) {
    Application test1=Test::instance();
    //Test test2=static_cast<Test>(test1);
    test1.setName("bla");
    test1.printer(test1.getName());
}

正如预期的那样,test1无法调用.printer()方法,因为返回的对象是“Application”类型。有没有办法将派生类的类型传递回主类并创建派生类的实例?

编辑:我已经使用CRTP传递了值,但是当我执行以下操作时它并不相同:

Test test1=Test::instance();
Test test2=Test::instance();
cout<<"Is test1 the same as test 2? "<<(&test1==&test2)<<endl;

结果总是 FALSE

1 个答案:

答案 0 :(得分:5)

您还需要将复制构造函数和赋值设置为私有,以便无法复制对象(因为只有对象必须存在)。

在您的代码中

Test test1=Test::instance();
Test test2=Test::instance();

你实际上是在打电话

Test test1(Test::instance());

实际上正在调用

Test (const Test &);

这是复制构造函数,因此创建了对象的副本。而你实际上是在创建两个不同的对象。这就是地址不同的原因。

因此,将复制构造函数和赋值运算符设为私有,以便没有人可以复制它。

并使用以下

Test & test1 = Test::instance();
Test & test2 = Test::instance();

在这种情况下,地址将相同。

或者,如果需要,您可以在Test::instance中返回指针。