Reputation: 3839
Here is what I try to do (as the title of the question might not describe the entire problem well).
In the program I would like to write, I need to dynamically create instances of an object which I store in a vector list.
class A {...};
int main()
{
std::vector<A *> as;
as.push_back(new A);
as.push_back(new A);
...
return 0;
}
Once the vector has have been filled up with "As" I would like to "pass it on" to a singleton 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;
}
Ideally I'd like to find a way of passing the vector list declared in main() to to the singleton and being sure that the "as" in the Singleton aren't modifiable anymore (hence the const).
The reason for this is because I'd like then the Singleton to keep reusing objects from the vector list (Singleton::as), but I want to be sure that at no point in the program, this list gets modified once the Singleton is being used.
I did my best to describe what I would like to do. Maybe there is a pattern for doing this. I have no idea if this design make sense or more importantly I can't see how to implement something like this (I can't seem to find a way of initializing a const member variables of Singleton before the singleton is being used - it seems to defy the concept of the Singleton itself, since static Singleton instance
will be created as soon as the program is run).
It seems like it might be possible if I somehow declare std::vector not in main() but as a global variable, but I'd like to avoid using global variable if possible.
Any suggestion, help, ideas would be welcome.
Upvotes: 0
Views: 2161
Reputation: 308452
In order to initialize a const
member of an object, you must do it in the initializer list of the constructor. That means you are forced to make it part of the instance
function. You can layer this so that instance
doesn't take a parameter, but calls create_instance
which does.
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);
}
For completeness you should put some error checking that throws an exception if create_instance
is called more than once with a non-null parameter.
Upvotes: 0
Reputation: 218098
You may initialize the const member in constructor with an helper method:
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()){}
Upvotes: 1
Reputation: 50026
You can pass as
as a pointer in instance
method parameter, which has default value nullptr
, example below:
note that I have changes instance
method to be static
. Whether this is a good design, I don't know, I have never used code like that.
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();
}
Upvotes: 0