好吧,也许我太麻烦了,无法考虑解决这个问题的方法,我在互联网上看了很多类似的问题,但没找到。所以这是我可怕的代码:
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”中引用:Y& __thiscall Y :: operator =(class Y const&)“(?? 4Y @@ QAEAAV0 @ ABV0 @@ Z)
我很困惑,无法弄清楚虚函数路由机制如何让我调用X :: operator =(const X&)。有什么想法吗?
答案 0 :(得分:4)
Y
没有复制赋值运算符。它有X
的赋值运算符,但这不是一回事。所以编译器会生成一个。生成的运算符以非虚方式自动调用X
的赋值运算符,即它实际上想要调用X::operator=
,而不是覆盖它。
Z
还会获得一个生成的赋值运算符,该运算符调用Y
的赋值运算符。因此,您可以参考X::operator=
的实际实现,但您没有提供。
但更重要的是,分配和层次结构并不能很好地融合。您将遇到切片问题。不要使属于多态层次结构的类可分配(或可复制)。这不是一个好主意。
答案 1 :(得分:0)
Z类的编译器生成的operator =
将调用基类中的那个。