Eyal K.
Eyal K.

Reputation: 1072

Marking a member variable to not copy

I have a class that contains POD members. I need to have all members copied, except one (member a in the example case). The way I'm doing it right now is as follows:

class Example
{
private:
    int a = 0;
    int b = 0;
    int c = 0;
    int d = 0;
    double e = 0;

public:
    Example& operator=(const Example &rhs)
    {
        b = rhs.b;
        c = rhs.c;
        d = rhs.d;
        e = rhs.e;         

        return *this;
    }

    Example() {};

    Example(const Example& toCopy)
    {
       *this = toCopy;
    }
};

Is there a way to mark the variable to not copy, as doing it this way is verbose and prone to bugs if I later modify this class?

Upvotes: 2

Views: 656

Answers (2)

eerorika
eerorika

Reputation: 238311

No, you cannot make the implicit copy assignment skip members. Defining a custom assignment operator as you have done is the way to achieve your desired behaviour.

Doing it this way is verbose and prone to bugs if I later modify this class

You can group the copied members into a single subobject. That way the custom copy assignment is not fragile to changes and verbosity remains constant in relation to number of copied members.

Bonus: You don't need to specify value initialization for the members separately, but one for the entire subobject is enough.

class Example
{

    int a = 0;
    struct {
        int b;
        int c;
        int d;
        double e;
    } state = {};

public:
    Example& operator=(const Example &rhs)
    {
        state = rhs.state;
        return *this;
    }
...

Since the members are private this won't change the existing API of the class.

Upvotes: 1

Nir Friedman
Nir Friedman

Reputation: 17704

You can wrap the "odd man out", a, in a struct and define that structs behavior separately:

class Example
{
private:
    CopyLess a;
    int b = 0;
    int c = 0;
    int d = 0;
    double e = 0;

    struct CopyLess {
        int a = 0;
        CopyLess& operator=(const CopyLess&) { return *this; }
        CopyLess(const CopyLess&) {}
    };              
};

Note that I didn't bother writing any special members for Example anymore because the defaults do what you want. Writing code this way to avoid writing special members as much as possible is called the "Rule of Zero", more information and examples: http://www.nirfriedman.com/2015/06/27/cpp-rule-of-zero/.

Upvotes: 3

Related Questions