Reputation: 777
I am looking for a way to have my constructor make a reference to another object in this way:
Foo object1("File1");
Foo object2("File1");
The first object is created normally. The second object sees that there is already an object that is using the "File1" parameter and makes itself a reference to the first object. I know this may not be directly possible to do this in this manner. I keep a static vector of Foo* to keep track of the allocated objects.
I know that I can make all the members of the class pointers and for the first case create (New) them. In the second case, I would not create them and point them at the first object. Also the second object is guaranteed to have a shorter lifetime than the first.
So, is there an easy/elegant way to do this?
EDIT: Thank you for all the great solutions. I like them all, but I can only use one. I will keep all of this knowledge for future reference tho.
I am selecting the static map <string, FooObject*>
solution. At first I thought it was stupid, but upon further review, it appealed to me as elegant.
The only addition that I can see right now would be to add a link counter to the FooObject. This way in the constructor of Foo I can increment the link counter. In the destructor, decrement the counter. If counter is then zero, remove it from the map. This way there is no memory leaks, and the objects can get destructed in any order. I guess this methodology is shared_ptr esque. Credit goes to @Travis for this.
Thanks, James.
Upvotes: 5
Views: 261
Reputation: 2611
Try to use static map<string, object*>
as variable where object is the rest of the class you need.
Upvotes: 6
Reputation: 23168
You just need a factory method that returns Foos and always call it expecting a reference. Then you store them in a static map and you check for them when you are asked.
Foo &file = getmefile("file1");
Foo &file2 = getmefile("file1");
Foo &getmefile(string filename){
if (foos.find(filename) == foos.end() ) {
foos[filename] = Foo(filename);
}
return foos[filename];
}
Upvotes: 0
Reputation: 96233
This sounds possibly like flyweight http://en.wikipedia.org/wiki/Flyweight_pattern
If you're in a single-threaded environment you could just have a static std::map<std::string, ObjectImpl*>
in your class and used by your constructor. You would use the pimpl pattern to store the actual implementation and when an object is created check to see if the implementation is already available. If it is, just set the pointer immediately. If you need to clean up when there are no references left, you can add additional code to handle that as well.
Upvotes: 0
Reputation: 20780
You can use a resource manager. It should have an interface like this:
class ResourceManager
{
public:
Foo* GetFoo(some id type, maybe file name);
void ReleaseFoo(Foo* fooObj);
}
Inside it will search if there is Foo* object that uses same id like the new id and if this exits it will return old Foo* object else it will create a new object of type Foo*. It will also count the number of Foo* objects for every id. When Release function is called it will decrement the number for that id(that identifies in a unique the object) and if it's 0 it will delete the object.
This is the most simple way of doing this. You can have it running in another thread for more that one type of resource and other stuff, but this is the basic idea.
Upvotes: 1