c++ copy constructor - implicit copy for all but one field?
Asked Answered
V

3

6

Supose I have a class containing many fields, and/or is constantly changing (in development), and all its fields are either natives or of not-necessarily-POD types which provide a satisfactory copy-constructor, but one - which might has even deleted or privatize its copy-constructor, yet provides me with ways of doing the copy as I need.
Now suppose I need it to have a copy-constructor of its own.
Am I bound to write the exhaustive (exhausting) field by field copy, or is there a cleaner, less exposed to bugs, way to achieve the same goal?

illustration code :

class Big {
public :
  Big(Big const & big) : ? { ? }
protected :
  int i1, i2, ... , i50;
  float f1, f2, ... , f50;
  CopyConstructableClass1 c1;
  CopyConstructableClass2 c2;
  ...
  CopyConstructableClass20 c20;
  NonCopyConstructableClass ncc;
};

Thanks

Vasquez answered 30/11, 2015 at 21:58 Comment(0)
G
4

You could wrap the obnoxious class in question into a sanely copyable class of your own design, and then make the field in your big, changing class to be of that wrapper type rather than the original type. That way you only need to do the work of the "custom copying" once in one place, and you can reuse that logic later elsewhere.

This is following the single responsibility principle, which states that every class should have precisely one responsibility, and complexity is built by composition.

Gerrard answered 30/11, 2015 at 22:8 Comment(0)
M
1

Usually what I do in this case is to put all the fields which can copy themselves into base class. Than I can have a derived class with just one field, which will be copied manually.

To emphasize the fact that this base class is not to be used on it's own, it is prudent to mark it's destructor protected. Actually, all of it's members can be.

Metaplasia answered 30/11, 2015 at 22:3 Comment(2)
I thought about it while writing down the question, but it felt just wrong (esthetical-wise). The above answer has a rather better approach.Vasquez
@elad, it is up to you. I hate to have to prefix all the members of that inner class with class name, and I think, this is a valid case of inheritance. You might have different aesthetical views.Metaplasia
B
-1

Consider something that would skip assignment operator logic. As an example (not real code):

template <typename T>
class DontCopyThisField : public T
{
public:
    template <typename... Args>
    DontCopyThisField(Args&&... args):
        T(std::forward<Args>(args)...)
    {
    }

    DontCopyThisField(const DontCopyThisField& from)
    {
    }

    DontCopyThisField(DontCopyThisField&& from):
        T(static_cast<T&&>(from))
    {
    }

    DontCopyThisField& operator=(const T& from)
    {
        T::operator=(from);
        return *this;
    }

    DontCopyThisField& operator=(T&& from)
    {
        T::operator=(std::move(from));
        return *this;
    }

    DontCopyThisField& operator=(const DontCopyThisField& from)
    {
        return *this;
    }

    DontCopyThisField& operator=(DontCopyThisField&& from)
    {
        T::operator=(static_cast<T&&>(from));
        return *this;
    }
};
Brandes answered 3/4, 2017 at 23:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.