初始化单例的const成员变量

Initializing const member variables of a singleton

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

在我想编写的程序中,我需要动态创建 object 的实例,并将其存储在向量列表中。

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

向量填满后 "As" 我想 "pass it on" 到单例 object.

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() 中声明的向量列表传递给单例,并确保单例中的 "as" 不再是可修改的(因此 const ).

这样做的原因是因为我希望 Singleton 继续重用向量列表 (Singleton::as) 中的 objects,但我想确保程序,一旦使用 Singleton,此列表就会被修改。

我尽力描述了我想做的事情。也许有一种模式可以做到这一点。我不知道这个设计是否有意义,或者更重要的是我看不到如何实现这样的东西(我似乎找不到在使用单例之前初始化 Singleton 的 const 成员变量的方法 - 看起来违背单例本身的概念,因为 static Singleton instance 将在程序 运行) 时立即创建。

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

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

您可以将 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();
}

您可以使用辅助方法在构造函数中初始化 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()){}

为了初始化对象的 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);
}

为了完整起见,如果使用非空参数多次调用 create_instance,您应该进行一些错误检查以抛出异常。