提问人:prestokeys 提问时间:1/30/2023 最后编辑:prestokeys 更新时间:1/30/2023 访问量:103
仅分配部分时赋值运算符的问题
Problem with assignment operator when assigning partially only
问:
请考虑此代码。我定义了一个复制构造函数,它将复制除一个数据之外的所有数据,即其数据成员。但是我似乎无法用赋值运算符完成同样的事情。除了我在下面已经做过的事情之外,最好的方法是什么?目前,我仅通过手动设置成员来完成。如果有数百个成员需要复制,只有一个成员不能复制,该怎么办?复制构造函数处理此问题,但赋值运算符不处理。Person
DontCopy
name
Person
#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
答:
0赞
44stonelions
1/30/2023
#1
如果不想单独复制每个数据成员,可以将所有要复制的数据放在另一个结构中,类似于“不复制”结构。将要复制的所有数据成员放入结构中,然后将结构复制到新对象上。
但是,对于一个类来说,这不是一个特别好的设计。我建议,如果你有一个既有数百个数据成员又需要复制构造函数的类,你最好重新设计这个类并将其分解一下。
在复制构造函数中有一个非复制数据成员也存在问题。当你复制一个对象时,大多数人都希望你收到的是该对象的精确副本,而不是缺少某些东西的部分副本。如果有人试图将对象的副本传递给函数,并且没有查看复制构造函数正在执行的操作,这可能会导致错误。
如果类包含不应复制的数据,最好只将复制构造函数标记为已删除,并使该类不可复制。如果你真的需要部分复制行为,你可以将其添加为一个方法,其名称可以更明显地表明它正在做什么。
评论
PersonDataDoCopy::operator=(other);