仅分配部分时赋值运算符的问题

Problem with assignment operator when assigning partially only

提问人:prestokeys 提问时间:1/30/2023 最后编辑:prestokeys 更新时间:1/30/2023 访问量:103

问:

请考虑此代码。我定义了一个复制构造函数,它将复制除一个数据之外的所有数据,即其数据成员。但是我似乎无法用赋值运算符完成同样的事情。除了我在下面已经做过的事情之外,最好的方法是什么?目前,我仅通过手动设置成员来完成。如果有数百个成员需要复制,只有一个成员不能复制,该怎么办?复制构造函数处理此问题,但赋值运算符不处理。PersonDontCopynamePerson

#include <iostream>
#define show(variable) std::cout << #variable << " = " << variable << '\n';

struct DontCopy {
    class Person& subject;
    DontCopy (Person& p) : subject(p) { }
};

class PersonDataDoCopy {
protected:
    std::string name;
    PersonDataDoCopy (const std::string& n) : name(n) { }
    PersonDataDoCopy() = default;
};

class Person : private PersonDataDoCopy {
    DontCopy dontCopy{*this};
public:
    Person (const std::string& n) : PersonDataDoCopy(n) { }
    Person (const Person& other) : PersonDataDoCopy(other) { }  // 'dontCopy' is not copied from 'other'.
    Person (Person&& other) : PersonDataDoCopy(std::move(other)) { }  // 'dontCopy' is not copied from 'other'.
    Person& operator= (const Person& other) {
        if (this == &other)
            return *this;
//      static_cast<PersonDataDoCopy>(*this) = PersonDataDoCopy(other);  // Does not copy data from PersonDataDoCopy
//      *this = static_cast<Person&>(PersonDataDoCopy(other));  // Does not compile.
        name = other.name;  // Need more general solution than this.
        return *this;
    }
    Person() = default;
    void display() const { show(name)  show(this)  show(&dontCopy.subject); }
};

int main() {
    Person bob("Bob");
    bob.display();
    std::cout << '\n';
    Person clone1(bob);
    clone1.display();
    std::cout << '\n';
    Person clone2("");
    clone2 = bob;
    clone2.display();
}

输出:

name = Bob
this = 0x6ffde0
&dontCopy.subject = 0x6ffde0

name = Bob
this = 0x6ffdd0
&dontCopy.subject = 0x6ffdd0

name = Bob
this = 0x6ffdc0
&dontCopy.subject = 0x6ffdc0
C++ 复制构造函数 赋值运算符

评论

0赞 273K 1/30/2023
问题是什么?你能更详细地描述它,而不是我似乎无法完成同样的事情吗?
0赞 Sam Varshavchik 1/30/2023
在第一条评论中,“不从 PersonDataDoCopy 复制数据”是什么意思?诚然,这不是 100% 正确的,但仍然应该进行复制,尽管它与县城无关。
2赞 Wyck 1/30/2023
当你尝试时发生了什么?试着用“预期结果”与“实际结果”来表达你的问题
3赞 yeputons 1/30/2023
也许你想写?就像这样,它是一个完整的 C++ 语句。PersonDataDoCopy::operator=(other);
0赞 prestokeys 1/30/2023
我更新了我的介绍,以帮助您更好地了解问题。

答:

0赞 44stonelions 1/30/2023 #1

如果不想单独复制每个数据成员,可以将所有要复制的数据放在另一个结构中,类似于“不复制”结构。将要复制的所有数据成员放入结构中,然后将结构复制到新对象上。

但是,对于一个类来说,这不是一个特别好的设计。我建议,如果你有一个既有数百个数据成员又需要复制构造函数的类,你最好重新设计这个类并将其分解一下。

在复制构造函数中有一个非复制数据成员也存在问题。当你复制一个对象时,大多数人都希望你收到的是该对象的精确副本,而不是缺少某些东西的部分副本。如果有人试图将对象的副本传递给函数,并且没有查看复制构造函数正在执行的操作,这可能会导致错误。

如果类包含不应复制的数据,最好只将复制构造函数标记为已删除,并使该类不可复制。如果你真的需要部分复制行为,你可以将其添加为一个方法,其名称可以更明显地表明它正在做什么。