简体   繁体   中英

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?

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/ .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM