Consider this code. I have defined a copy constructor for Person that will copy all data except for one, namely its DontCopy data member. But I can't seem to get the same thing done with the assignment operator. What is the best way to do it apart from what I've done already below? Currently, I've done it by manually setting the name member only. What if there are hundreds of members of Person that need to be copied, with only one that is not to be copied? The copy constructor takes care of this problem, but the assignment operator does not.
#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();
}
Output:
name = Bob
this = 0x6ffde0
&dontCopy.subject = 0x6ffde0
name = Bob
this = 0x6ffdd0
&dontCopy.subject = 0x6ffdd0
name = Bob
this = 0x6ffdc0
&dontCopy.subject = 0x6ffdc0