Ian Collins wrote:
> On 02/28/12 09:58 AM, Jorgen Grahn wrote:
>> On Mon, 2012-02-27, yatremblay@bel1lin202.(none) (Yannick Tremblay) wrote:
>>>
>>> We have the HomeForSale class. It is non-sensical to copy a
>>> HomeForSale and the concept a a default HomeForSale is also
>>> non-sensical (we don't live in dark utopia of default homes :-)
>>>
>>> But /just to avoid using any kind of pointers/, you find a way to
>>> implement copying and default construction that you then need to
>>> document to explain to future generation that they should never be
>>> used per se and that they are only a hack to fullfill the std::vector
>>> requirements...
>>
>> That's right. I assume most people do it that way.
>> (If most people here don't, I'd like to hear about it!)
>
> Well I wouldn't. I hardly ever store Ts in a vector. More often than not I use a
> container of shared_ptr<T>. Adding a copy constructor when your class design
> doesn't warrant one is poor form. Consider what will happen if you later need to
> add a reference member or a managed resource to your class.
I think this conversation would win from agreeing on some context, namely a
particular reason why you do not need copy constructor. As an example, if all
one needs from an object (in terms of creation/destruction) is to keep a
collection of them in an array and a standalone object is of no value (it's an
often situation in my practice when you need to dispatch messages to processors
and the processors are relatively rarely created/removed so you want to dispatch
in amortized constant time), std::vector comes to mind. Now it's up to you to
decide whether you introduce copy constructor or create a vector of pointers. If
objects are very small (say, these are some stateless policies or policies
thousands of which may share the state) but there are tons of them, vector of
pointers may create a significant waste, even if you use some pool allocator
(because in addition to an object, which is, say 4-8 bytes, you would have to
keep, say, 4-byte pointers in a vector -- this is a meaningful overhead). There
is also an additional indirection cost (which may, in some patterns, almost half
the effective CPU cache size).
Thus, you are facing a tradeoff: add a copy constructor (unnecessary copying in
this case is the only price; and does not seem significant because the objects
are relatively long-living; not much ideology/design purity considerations are
involved either IMHO) vs vector-of-pointers (with its meaningful additional
space and time costs).
Before C++11, I would probably add a copy constructor (in this particular
context). In C++11, emplace() gives you best of two worlds.
There can certainly be other considerations. For example, add some extra
reference to the message-dispatching processors described above ("extra" in a
sense that it is in addition to those kept by message sources (or logical
connections to them)) and you would be happy if you originally chose shared
pointer design.
IMHO, programming is all about applying abstract ideas to a concrete problem;
and the "concrete problem" part of the equation is at least as important as are
the abstract ideas. It often puzzles me when someone starts an argument on which
abstract idea is "better" without first agreeing on a meaningful context to
apply it.
....
-Pavel