动态调度OOP

时间:2016-03-13 10:21:25

标签: c++ oop

我在cpp中编写代码来测试我对动态调度的理解。我认为在我的程序中输出应该是" 我在NT "。我的理由是:

  1. tMethod被定义为虚拟,因此将使用动态绑定
  2. 在运行时test的类类型是NT,因此调用test->tMethod(ont)应该查找NT中的实现
  3. 实际参数ont的类型为NT,因此发现完全匹配是NT的tMethod强制执行
  4. 但是,该程序的输出是" 我在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;
        }
    

3 个答案:

答案 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;
}