我在cpp中编写代码来测试我对动态调度的理解。我认为在我的程序中输出应该是" 我在NT "。我的理由是:
test
的类类型是NT,因此调用test->tMethod(ont)
应该查找NT中的实现ont
的类型为NT,因此发现完全匹配是NT的tMethod强制执行但是,该程序的输出是" 我在T "中。
我的推理有什么问题?
#include <iostream>
using namespace std;
class T {
public:
virtual void tMethod(T){
cout<<"I'm in T"<<endl;
}
};
class NT: public T{
public:
void tMethod(NT){
cout<<"I'm in NT"<<endl;
}
};
int main()
{
NT ont;
T* test=new NT();
test->tMethod(ont);
return 0;
}
答案 0 :(得分:5)
此方法:
void tMethod(NT){
不会覆盖这一个:
virtual void tMethod(T){
您已将参数类型从NT
更改为T
您可以添加覆盖以将此错误转为错误:
void tMethod(NT) override {
将输出:
main.cpp:16:18:错误:'void NT :: tMethod(NT)'标记为'覆盖',但不覆盖 void tMethod(NT)覆盖{
[编辑]
您的实际问题是为什么C ++不允许跨类继承重载函数,特别是为了能够使用基类指针访问派生类函数。原因是语言不支持此功能。您可以在Bjarne Stroustrup FAQ中找到类似的问题:Why doesn't overloading work for derived classes?
答案 1 :(得分:2)
arr
将不同的参数类型赋予NT::tMethod()
,因此不会覆盖。使用N::tMethod()
关键字来防范此问题:
override
现在您应该收到编译错误,因为您将#include <iostream>
using namespace std;
class T
{
public:
virtual void tMethod(T) {
cout << "I'm in T" << endl;
}
};
class NT: public T
{
public:
void tMethod(NT) override { // use override keyword here
cout << "I'm in NT" << endl;
}
};
int main()
{
NT ont;
T* test = new NT();
test->tMethod(ont);
return 0;
}
标记为MT::tMethod()
,但它没有,因为它采用了不同的参数类型。
答案 2 :(得分:1)
最好使用指针或对基类的引用作为虚方法中的参数。如果需要在overriden方法中使用派生类,则可以使用dynamic_cast。
class T {
public:
virtual void tMethod(T*){
cout<<"I'm in T"<<endl;
}
};
class NT: public T{
public:
virtual void tMethod(T* t) override {
NT* nt=dynamic_cast<NT*>(t);
if (nt)
{
cout<<"I'm in NT as NT"<<endl;
}
}
};
int main()
{
NT ont;
T* test=new NT();
test->tMethod(&ont);
return 0;
}