4

我有一个继承自 MSFT 类的类,因此无法更改,我希望派生类的复制构造函数和复制赋值运算符具有相同的行为。我遇到的麻烦是,在复制构造函数中,您可以自由地为初始化列表中的基类调用构造函数,但在运算符中,这不是一个选项。如何在赋值运算符中正确地重新创建此行为?仅在运算符重载的主体中调用基类的构造函数就足够了吗?

附加说明:基类继承自 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 注释

4

2 回答 2

7

在一般情况下,您可以通过为基类子对象显式调用 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”关系。您的 Base 无法复制。你的派生是一个基础。因此,您的 Derived 也无法复制。

于 2013-04-04T14:47:32.080 回答
4

像这样

Derived& operator=(const Derived& rhs)
{
    Base::operator=(rhs);
    derivedInt = rhs.derivedInt;
    return *this;
}
于 2013-04-04T14:45:20.303 回答