本人在VS2015中编写了一个简单的C++程序来测试虚函数的运行情况。结果发现将运算符重载函数设置成虚函数是没有效果的(即程序根据引用或指针的类型来选择调用哪个类的方法,而不是根据引用或指针所指向的对象的实际类型来选择调用哪个类的方法)。
讨教各位是这个样子的吗,或是哪里出错了。
下面先附上源代码:
讨教各位是这个样子的吗,或是哪里出错了。
下面先附上源代码:
#include <iostream> using namespace std; class Num { protected: int num; public: Num(int n = 0); virtual void show(void) const { cout << "in Num class: " << num << endl; } virtual Num & operator=(const Num &); }; class NumPlus : public Num { private: double decmals; public: NumPlus(int n = 0, double d = 0.0); virtual void show(void) const { cout << "in NumPlus class: " << num + decmals << endl; } virtual NumPlus & operator=(const NumPlus &); }; Num::Num(int n) { num = n; } /*本人定义的赋值运算符函数,仅做测试用*/ Num & Num::operator=(const Num & n) { cout << "in Num operator=\n"; num = 33; return (*this); } NumPlus::NumPlus(int n, double d) : Num(n) { decmals = d; } /*本人定义的赋值运算符函数,仅做测试用*/ NumPlus & NumPlus::operator=(const NumPlus & np) { cout << "in NumPlus operator=\n"; num = 66; decmals = 0.6; return (*this); } int main(void) { NumPlus a; a.show(); NumPlus b(1, 0.2); b.show(); Num & ra = a; Num & rb = b; ra.operator=(b); //实际上使用了Num::operator=(); ra.show(); //使用了NumPlus::show(); a.operator=(b); ra.show(); return 0; }
对程序做一下说明:
基类Num包含一个保护数据成员num,基类的虚函数show()用来显示num的值。
派生类NumPlus添加了一个数据成员decimals,派生类的虚函数show()显示num+decimals的值。
Num::operator=()和NumPlus::operator=()是本人定义的,只是将数据成员赋值成固定的值,仅仅用来测试。
下面是运行结果:
结果中的第3、4行对应源代码的第71、72行。其中ra.operator=(b)调用的是基类的方法,而ra.show()成功调用派生类的方法。
啊,考虑到赋值运算符重载的特殊性,本人将operator=()替换成operaotr+()进行测试,还是如上述结果一样。
讨教各位,将运算符重载设置成虚函数能否具有实际作用
解决方案
20
函数参数都不同,这是两个不同的虚函数了
30
重载的虚函数要求参数类型一样才算重载,所以这的运算符只不过是两个不同的虚函数而已
5
本人觉得是无效的,可以这么想,父类中有一个this指针,子类中也有一个this指针,假如子类中赋值运算要重载父类中的赋值运算符,会导致this指针的二义性问题,这个this指针不知道要指父类中的成员还是子类中的成员。