Ian said:
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