这两种调用基类复制赋值的方法有什么区别



假设我有以下内容:

class A
{
public:
    A& operator= (A const& other)
    {
        return *this;
    }
};
class B : public A
{
public:
    B& operator= (B const& other)
    {
        static_cast<A&>(*this) = static_cast<A const&>(other);
        // or...
        A::operator=(other);
        return *this;
    }
};

要调用A版本的副本分配运算符,我可以执行以下任一操作:

static_cast<A&>(*this) = static_cast<A const&>(other);

或者:

A::operator=(other);

你为什么要选一个而不是另一个?两者之间有什么区别?

编辑

我的问题最初的例子是无效的,与我想要问的相去甚远。我为这个错误道歉。我已经更新了上面的例子,使其更加清晰。

static_cast<A&>(*this).foo()仍然调用foo的派生版本。这只是通过基类引用调用一个虚拟函数。

A::foo()关闭虚拟调度并调用在类A中实现的foo,而不是在派生类中实现的。


如果operator=A中不是虚拟的,则static_cast<A&>(*this) = static_cast<A const&>(other)是表示A::operator=(other)的另一种方式(不需要上广播other,因为派生到基引用的转换是隐式的)。他们做同样的事情——调用A::operator=

然而,operator=通常是根据复制构造函数和交换来实现的

B& B::operator=(B other) { 
    other.swap(*this); 
    return *this;
}

B的值为我们调用B的复制构造函数。如果B有r值复制构造函数,则此赋值运算符可以与r值一起使用,也可以仅移动B(例如,如果Bstd::unique_ptr成员)。

如果您想为两个类(A和B)都使用A赋值运算符,请不要在B类中实现它。

最新更新