> > If you want references to objects within the > containers, > > maybe you should use containers of pointers, and then > the > > pointers can be moved around without invalidating your > > references (to the objects pointed to). Yes, I guess > > that's a layer of indirection, and you probably already > > thought of this... > > This is almost the point of my post. STL containers > shouldn't be used to allocate the objects even though they > were designed to, but rather to hold pointers to objects > allocated by a separate factory class.
Others have pointed out that you can handle the allocation, yourself, by providing allocators, if you like (like your "object management" classes). If you want to handle it externally, then, pointers or smart pointers may be used in the container, instead.
I think there may be a little confusion, here: As has been mentioned, the STL containers are defined to use value semantics, so they are mostly appropriate for light-weight objects (at least if you intend to move things around a lot). However, "object" in "C++ speak" means "value", and it can be a built-in value like "int", a pointer, an object of a user-defined type, etc.
In this light, what you say here: "STL containers shouldn't be used to allocate the objects even though they were designed to, but rather to hold pointers to objects allocated by a separate factory class" doesn't make a lot of sense. Yes, they are designed to hold objects, and, yes, pointers are also objects, so there's no contradiction: it can be used for either, and there's no need for an "object manager", if the objects are lightweight enough (or it makes sense) to be stored directly.
Two broad classes of objects are "value objects" and "entity objects". A "value object" is completely determined by its attributes, typically immutable, and may be copied. An "entity object" have more emphasise on its identity, is typically mutable, and non-copyable. The latter kind is typically mangaed through some "handle", like a pointer or smart pointer.
What you describe sound more like storing "entity objects" in containers, for which they are are not suitable (by design - objects stored must be copyable). Furthermore, as mentioned, the separation you talk about seems to fit the container/allocator separation, which already exist.
> > >> struct fubar { }; > > >> fubar x; > > >> std::vector<fubar> v; > > >> v.push_back(x); // the vector makes an internal copy > of > > the object, therefore it is a factory. > > > struct fubar { }; > > fubar x; > > fubar v[1]; > > v[0] = x; // the array makes an internal copy of the > > object, therefore it is a factory. > > I should have said, when you call v.push_back, the vector > uses the allocator to create an empty instance of the type > fubar, and then copies x into it.
To be precise, the allocator allocates _memory_ for the object - it doesn't construct it (yes, I know the allocator interface is confusing - it returns a pointer to an array of elements of the type, but the objects are not there...), where objects are then copy-constructed from the provided value.
> It is not the fact that it makes a copy, but the fact that > the vector uses an allocator class to create a new object > instance dynamically, which makes it a factory.
That's a quite unusual use of the term "factory", although for one kind of factory, "prototype factory", this is actually what happens (it creates a new value by copying an existing one).
> I should point out that I can see how it can be argued > that the standard containers "use" factories but are not > themselves factories. I call them factories because they > expose the dynamically created -- and not just > copy-created as Greg suggests, e.g. > std::vector.resize(int)
std::vector.resize() actually takes the object to insert as its second argument... defaulted to a default-constructed element. Thus, the values in the container are copy-constructed, even in this case (http://www.sgi.com/tech/stl/Vector.html):
void resize(n, t = T())
Regards,
Terje
Flat View: This topic has 17 replies
on 2 pages
[
«
|
12
]