在复制赋值运算符中指定基类成员

4
我有一个继承自微软类的类,因此无法更改,我希望我的派生类在其复制构造函数和复制分配运算符中具有相同的行为。问题是,在复制构造函数中,您可以在初始化列表中调用基类的构造函数,但在运算符中,这不是一个选项。如何正确地在赋值运算符中重新创建此行为?只在运算符重载的主体中调用基类的构造函数是否足够? 附加说明:基类继承自CObject,该类的operator=()和复制构造函数被设置为私有和未实现的方法,因此不幸的是任何对它们的调用都将导致编译错误。
以下是一个简化的代码示例:
类声明:
class Base    
{
protected:
    int baseInt;
public:
    Base(int);
}

class Derived : public Base
{
public:
    Derived(const Derived& other);
    Derived& operator=(const Derived& rhs);
private:
    int derivedInt;
}

派生类成员函数:

// Copy Constructor
Derived(const Derived& other) : Base(5)
{
    derivedInt = other.derivedInt;
}

// Copy Assignment Operator
Derived& operator=(const Derived& rhs)
{
    if (&rhs != this)
    {
        derivedInt = other.derivedInt;
        return *this;
    }
}

编辑:更新了语法并添加了CObject注释


2
Base(5); 只是创建一个临时的 Base 对象,然后立即销毁它... - Oliver Charlesworth
@OliCharlesworth 我就猜到会发生这种情况 :/ 我不太熟悉如何重新创建初始化列表的操作,所以这只是一次碰运气。 - CJ McAllister
2个回答

8

一般情况下,您可以通过显式调用基类子对象的operator=来完成此操作,或者使用copy&swap惯用语(如果可用):

//explicit call to base operator=
Derived& operator=(const Derived& rhs)
{
  Base::operator=(rhs); //
  derivedInt = rhs.derivedInt;
  return *this;
}


//or copy&swap:
Derived& operator=(const Derived& rhs)
{
  Derived tmp(rhs); //copy
  tmp.swap(*this);
  return *this;
}

void swap(Derived& other)   
{
  Base::swap(other);
  std::swap(derivedInt,other.derivedInt);
}

更新:由于您的基类不应被复制分配,那么您的派生类也不应该被复制分配。有些情况下,类包含不可复制的部分但是可以完全复制。在这些情况下,不可复制的部分是一些并没有直接影响到类对象状态的东西,例如唯一ID。然后这些部分通常不会在赋值期间改变。然而,在这些情况下,不可复制的部分不应该通过继承来实现,而应该通过聚合来实现。

简单来说:继承意味着“is-A”的关系。您的基类不能被复制,您的派生类是基类。因此,您的派生类也不能被复制。


虽然这似乎在大多数情况下都可以工作,但我最终是从CObject继承的,它的赋值运算符/复制构造函数是私有的。此外,swap()在基类或任何基类中都没有实现,因此也不起作用 :/ 我已经更新了我的问题以反映这一点。 - CJ McAllister
好的,谢谢。我的静态分析工具抱怨缺少operator=,所以我认为它必须存在,尽管在基类中是私有的。感谢您提供的信息! - CJ McAllister
1
是的和不是。您的静态分析工具会发出警告,一些编译器会警告未定义的operator=,因为它不能像通常一样由编译器生成。这是由于noncopyable基类造成的,使您的派生类隐式不可复制。为了提高可读性并消除工具的警告,您可以显式地声明您知道您的派生类是不可复制的,并且这是有意的-通过将copyctor和赋值运算符声明为私有(C++03)或明确删除它们(C++11)。 - Arne Mertz

5

像这样

Derived& operator=(const Derived& rhs)
{
    Base::operator=(rhs);
    derivedInt = rhs.derivedInt;
    return *this;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接