初始化单例的const成员变量

时间:2015-04-13 16:17:35

标签: c++ design-patterns singleton

这是我尝试做的事情(因为问题的标题可能无法很好地描述整个问题)。

在我想写的程序中,我需要动态创建一个对象的实例,我将它存储在一个向量列表中。

class A {...};
int main()
{
    std::vector<A *> as;
    as.push_back(new A);
    as.push_back(new A);
    ...
    return 0;
}

一旦向量填充了“As”,我想“将其传递给”单个对象。

class Singleton
{
private:
    Singleton() {}
    // set this with the content of ::as created in main?
    const std::vector<A*> as;
public:
    Singleton& instance()
    {
        // how can I set 'as' before the instance is returned/even created?
        static Singleton instance; return instance;
    }
};
...
int main(...)
{
    std::vector<A *> as;
    as.push_back(new A);
    as.push_back(new A);
    ...
    // I'd like Singleton::as to be set with the content of 'as'
    // before I use the singleton for the first time?
    Singleton::instance.doSomethingWithAs();
    return 0;
}

理想情况下,我想找到一种方法将main()中声明的向量列表传递给单例,并确保Singleton中的“as”不再可修改(因此为const)。

原因是因为我希望Singleton继续重用向量列表中的对象(Singleton :: as),但我想确保在程序中没有任何一点,这个列表会被修改一次正在使用Singleton。

我尽力描述我想做的事情。也许有这样做的模式。我不知道这个设计是否有意义或更重要的是我无法看到如何实现这样的东西(我似乎找不到在使用单例之前初始化Singleton的const成员变量的方法 - 似乎无视Singleton本身的概念,因为一旦程序运行就会创建static Singleton instance

似乎有可能,如果我以某种方式声明std :: vector不在main()中而是作为全局变量,但我想尽可能避免使用全局变量。

欢迎任何建议,帮助和想法。

3 个答案:

答案 0 :(得分:1)

您可以使用辅助方法初始化构造函数中的const成员:

std::vector<A*> make_as()
{
    std::vector<A*> as;
    as.push_back(new A);
    as.push_back(new A);
    //..
    return as;
}

Singleton::Singleton() : as(make_as()){}

答案 1 :(得分:0)

您可以将as作为instance方法参数中的指针传递,该参数的默认值为nullptr,例如:

请注意,我将instance方法更改为static。这是否是一个好的设计,我不知道,我从来没有使用过这样的代码。

class A {};

class Singleton
{
private:
    Singleton(std::vector<A *>* p) : as(*p)  {}
    // set this with the content of ::as created in main?
    const std::vector<A*> as;
public:
    static Singleton& instance(std::vector<A *>* p=nullptr)
    {
        // how can I set 'as' before the instance is returned/even created?
        static Singleton instance(p); return instance;
    }

    void useMe() {
    }
};

int main()
{
    std::vector<A *> as;
    as.push_back(new A);
    as.push_back(new A);
Singleton::instance(&as);

Singleton::instance().useMe();
}

答案 2 :(得分:0)

为了初始化对象的const成员,必须在构造函数的初始化列表中执行此操作。这意味着您必须使其成为instance函数的一部分。您可以对此进行分层,以便instance不会参数,但会调用create_instance

Singleton(const vector<A*> * init) : as(*init)
{
}

Singleton& create_instance(const vector<A*> * init)
{
    static Singleton instance(init);
    return instance;
}

Singleton& instance()
{
    return create_instance(null_ptr);
}

为了完整性,如果使用非null参数多次调用create_instance,则应该进行一些引发异常的错误检查。