3

好吧,也许我太累了,无法思考这个问题的解决方案,我在互联网上看了很多类似的问题,但没有找到。所以这是我可怕的代码:

class X
{
public:
    virtual const X& operator =( const X& ) = 0;
};

class Y : public X
{
public:
         virtual const X& operator =( const X& x )
         {
             return *this;
         }
};

class Z : public Y
{
};


int main_08(int argc, char* argv[])
{
    Z z1;
    Z z2;
    z1 = z2;
    return 0;
}

根据我的预期,代码应该可以正常运行,因为由于类 Z 的赋值没有被覆盖,它应该指向定义的 Y 的赋值运算符。所以在写“z1 = z2”时,应该调用其基类的赋值运算符。当我注释掉这一行时,代码运行良好

相反,我得到 LNK2019 说:


错误 LNK2019:未解析的外部符号“public: virtual class X const & __thiscall X::operator=(class X const &)”(??4X@@UAEABV0@ABV0@@Z) 在函数“public: class Y & __thiscall”中引用Y::operator=(class Y const &)" (??4Y@@QAEAAV0@ABV0@@Z)


我很困惑,想不通虚函数路由机制是如何让我调用 X::operator =( const X& ) 的。有什么想法吗?

4

2 回答 2

4

Y没有复制赋值运算符。它有一个来自 的赋值运算符X,但这不是一回事。所以编译器生成一个。X生成的运算符以非虚拟方式自动调用' 赋值运算符,即它实际上想要调用X::operator=,而不是覆盖它的任何东西。

Z还得到一个生成的赋值运算符,它调用Y的赋值运算符。因此,您可以获得对X::operator=您未提供的实际实现的参考。

然而,更根本的是,分配和层次结构并不能很好地混合。你会遇到切片问题。不要使属于多态层次结构的类可分配(或根本可复制)。这不是一个好主意。

于 2013-06-14T11:50:48.243 回答
0

为类 Z生成的编译器operator =将调用基类中的那个。

于 2013-06-14T11:49:05.060 回答