c++ - Can we say bye to copy constructors? -
copy constructors traditionally ubiquitous in c++ programs. however, i'm doubting whether there's reason since c++11.
even when program logic didn't need copying objects, copy constructors (usu. default) were included sole purpose of object reallocation. without copy constructor, couldn't store objects in std::vector
or return object function.
however, since c++11, move constructors have been responsible object reallocation.
another use case copy constructors was, simply, making clones of objects. however, i'm quite convinced .copy()
or .clone()
method better suited role copy constructor because...
copying objects isn't commonplace. it's necessary object's interface contain "make duplicate of yourself" method, sometimes. , when case, explicit better implicit.
sometimes object expose several different
.copy()
-like methods, because in different contexts copy might need created differently (e.g. shallower or deeper).in contexts, we'd want
.copy()
methods non-trivial things related program logic (increment counter, or perhaps generate new unique name copy). wouldn't accept code has non-obvious logic in copy constructor.last not least,
.copy()
method can virtual if needed, allowing solve problem of slicing.
the cases i'd want use copy constructor are:
- raii handles of copiable resources (quite obviously)
- structures intended used built-in types, math vectors or matrices -
because copied ,vec3 b = a.copy()
verbose.
side note: i've considered fact copy constructor needed cas, cas needed
operator=(const t&)
consider redundant basing on exact same reasoning;
.copy()
+operator=(t&&) = default
preferred if need this.)
for me, that's quite enough incentive use t(const t&) = delete
everywhere default , provide .copy()
method when needed. (perhaps private t(const t&) = default
able write copy()
or virtual copy()
without boilerplate.)
q: above reasoning correct or missing reasons why logic objects need or somehow benefit copy constructors?
specifically, correct in move constructors took on responsibility of object reallocation in c++11 completely? i'm using "reallocation" informally situations when object needs moved someplace else in memory without altering state.
short anwer
is above reasoning correct or missing reasons why logic objects need or somehow benefit copy constructors?
automatically generated copy constructors great benefit in separating resource management program logic; classes implementing logic not need worry allocating, freeing or copying resources @ all.
in opinion, replacement need same, , doing named functions feels bit weird.
long answer
when considering copy semantics, it's useful divide types 4 categories:
- primitive types, semantics defined language;
- resource management (or raii) types, special requirements;
- aggregate types, copy each member;
- polymorphic types.
primitive types are, beyond scope of question; i'm assuming radical change language, breaking decades of legacy code, won't happen. polymorphic types can't copied (while maintaining dynamic type) without user-defined virtual functions or rtti shenanigans, beyond scope of question.
so proposal is: mandate raii , aggregate types implement named function, rather copy constructor, if should copied.
this makes little difference raii types; need declare differently-named copy function, , users need more verbose.
however, in current world, aggregate types not need declare explicit copy constructor @ all; 1 generated automatically copy members, or deleted if uncopyable. ensures that, long member types correctly copyable, aggregate.
in world, there 2 possibilities:
- either language knows copy-function, , can automatically generate 1 (perhaps if explicitly requested, i.e.
t copy() = default;
, since want explicitness). in opinion, automatically generating named functions based on same named function in other types feels more magic current scheme of generating "language elements" (constructors , operator overloads), perhaps that's prejudice speaking. - or it's left user correctly implement copying semantics aggregates. error-prone (since add member , forget update function), , breaks current clean separation between resource management , program logic.
and address points make in favour:
- copying (non-polymorphic) objects is commonplace, although it's less common can moved when possible. it's opinion "explicit better" or
t a(b);
less explicitt a(b.copy());
- agreed, if object doesn't have defined copy semantics, should have named functions cover whatever options offers. don't see how affects how normal objects should copied.
- i've no idea why think copy constructor shouldn't allowed things named function could, long part of defined copy semantics. argue copy constructors shouldn't used because of artificial restrictions place on them yourself.
- copying polymorphic objects entirely different kettle of fish. forcing types use named functions because polymorphic ones must won't give consistency seem arguing for, since return types have different. polymorphic copies need dynamically allocated , returned pointer; non-polymorphic copies should returned value. in opinion, there little value in making these different operations similar without being interchangable.
Comments
Post a Comment