【发布时间】:2013-02-17 06:14:23
【问题描述】:
以下代码(来自 C++ FAQs 24.11)正在实现虚拟赋值运算符重载和覆盖:
#include <iostream> using namespace std; class B{ public: virtual ~B() throw(); virtual B& operator= (const B& b) throw(); }; B::~B() throw(){} B& B::operator= (const B& b) throw() { cout << "B::operator=(const B&)\n"; return *this; } class D : public B{ public: virtual D& operator= (const B& b) throw(); D& operator= (const D& d) throw(); }; D& D::operator= (const B& b) throw() {cout << "D::operator= (const B&)\n"; return *this;} D& D::operator= (const D& d) throw() {cout << "D::operator= (const D&)\n"; return *this;} void sample(D& d, B& b, D& d2, B& b2){ cout << "d = d2: "; d = d2; cout << "d = b2: "; d = b2; cout << "b = b2: "; b = b2; cout << "b = d2: "; b = d2; } int main() { D d, b, d2, b2; sample(d,b,d2,b2); }
它说输出是:
- d = d2: D::operator=(const D&)
- d = b2: D::operator=(const B&)
- b = b2: D::operator=(const B&)
- b = d2: D::operator=(const B&)
上面写着:
"因为编译器会根据 参数的静态类型,第一个赋值是唯一的 调用接受 D 的赋值运算符;其他的都结束了 调用带 B 的赋值运算符。”
和
"最后两个调用解析为覆盖 (D::operator= (const B&)) 因为 sample() 中 b 的实际类是 D。如果 b 实际上是 a B,最后两个调用将解析为 (B::operator= (const B&))"
我有点迷糊,第一段说编译器看参数静态类型来确定使用哪个(重载?)函数调用,那么为什么最后一个case调用B参数类型的操作符,当传递的参数 d2 在 sample() 中被声明为类型 D& d2?
编辑参考下面的答案,我看不出对 B::=(D) 的请求如何导致 D::=(B)。如果有另一个子类 E 怎么办?为什么会调用 D::=(B) 而不是 E::=(B)?我们是说如果 B 没有参数 (D) 的函数“=”,那么运行时开始查看是否有任何派生对象包含这样的签名?
【问题讨论】:
标签: c++ inheritance virtual overloading assignment-operator