2015-06-24 108 views
-1

帮助?我真的不知道这里发生了什么? 为什么在分配的第3行中,当B分配给B时,它会调用A的operator =?C++ operator =怪异behviour

class A{ 
public: 
    A& operator=(const A&){cout << "A assignment" << endl;return *this;} 
}; 

class B:public A{ 
public: 
    A& operator=(const A&){cout << "B assignment" << endl;return *this;} 
}; 

int main() { 
    A a; 
    B b; 
    B b2;  
    a=b; // output: A assignment 
    b=a; // output: B assignment 
    b=b2; // output: A assignment WHY?? 
    return 0; 
} 
+0

[不编译](http://ideone.com/TWtPTP) –

+0

这样编译? –

+0

@jafar查看我之前的评论。 –

回答

1

你在B定义的赋值运算符,但也有编译器生成的另一个隐含的拷贝赋值运算符:

B& B::operator=(B const&); 

这比一个需要A const&所以它选择了一个更好的匹配在分配b = b2(因为b2B它不需要从一个A一个派生到基地转换)。隐含的拷贝赋值运算符调用你写的基类的拷贝赋值运算符:

B& B::operator=(B const& b) { 
    A::operator=(b); 
    return *this; 
} 

这就是为什么它看起来像A::operator=(A const&)正在被分配选择。

+0

看来你是对的,除非我明确地重载B&B :: operator =(B const&b)我的自我,它会做你说的那样。 –

2

B类中它仍然有一个编译器生成的赋值运算符(它被重载)。与构造函数的工作方式不同,定义一个或多个赋值运算符重载不会阻止编译器在缺少赋值运算符时生成复制赋值运算符。编译器生成一个调用A::operator=。对于B类型的参数来说,这是更好的匹配。

+0

它是如何更好地匹配tho?他们完全一样,不是吗? –

+0

@MichaelPapkov:一个重载(用户定义)需要一个'A const&',另一个(编译器生成)则需要一个'B const&'。 –