我有一个类Base
class Base{
public:
virtual ~Base();
//I'm not sure about this, should it be virtual, or should it be "pure" virtual?
virtual Base& operator=(const Base&);
}
如果类Base
由几个类派生,例如
class Derived1: public Base{
//...data
//standard assignment operator, it works for objects of class Derived1
Derived1& operator=(const Derived&){
//perform deep copy here
std::cout<<"Derived1 assignment operator"<<std::endl;
}
}
这些类中的每一个都必须具有赋值运算符,因为这些类的某些数据成员是指针,我必须将它们深拷贝。然后以下代码不起作用:
Base *d1 = new Derived1();
Base *d1_another = new Derived1();
//assignment operator is not called.
*d1 = *d1_another
如果我使基的赋值运算符是纯虚拟的,virtual Base& operator=(const Base&) = 0
,那么它必须在每个子类中实现。
class Derived1: public Base{
//...data
//implementation of the base's assignment operator
Base& operator=(const Base&){
//how to access Derived1 fields? Casting?
}
}
但是我如何复制子类的成员,如果传递给赋值运算符的对象是Base
?
附言我知道这不是一个非常好的设计,但是我应该怎么做,如果假设我有一个指向 Base std::vector<Base*> v
对象的指针向量,并且它充满了派生类的对象(Derived1
、Derived2
、一些其他类(,有时我必须将一个对象复制到另一个对象中。我不明白这样做的另一种解决方案是什么。
注意赋值运算符的参数不是Base
的对象,而是对Base
的引用。这意味着您可以使用例如 dynamic_cast
将其向下转换为对Derived1
对象的引用。
您还可以使用奇怪的重复模板模式(或 CRTP(在 Base
类中使用参数和返回的正确类型来声明赋值运算符。
我不会将operator=
用于这种事情。您如何处理将Derived2
分配给Derived1
?
相反,我会有一个指示成功或失败的assign
,例如
class Base{
protected:
Base& operator=(const Base&) = default;
Base& operator=(Base&&) = default;
public:
virtual ~Base() = default;
virtual bool assign(const Base&) = 0;
/* maybe ? virtual bool assign(Base&&) = 0; */
}
class Derived1: public Base{
//...data
protected:
Derived1& operator=(const Derived1 &) = default;
public:
bool assign(const Base & base){
if (const Derived1 * derived = dynamic_cast<const Derived1 *>(&base))
{
*this = *derived;
return true;
}
return false;
}
}
int main() {
Base *d1 = new Derived1();
Base *d1_another = new Derived1();
Base *d2 = new Derived2();
//assignment operator is not called.
assert(d1->assign(*d1_another)); // expect true, d1 is changed
assert(!d2->assign(*d1_another)); // expect false, d2 is unchanged
}