首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++多态函数匹配

C++多态函数匹配
EN

Stack Overflow用户
提问于 2016-05-25 23:29:59
回答 2查看 202关注 0票数 0

下面的代码带有带虚拟函数的链式继承,并打印:

代码语言:javascript
复制
D ptr
E

那么函数匹配的算法是什么,我猜是匹配最近的父类吗?但是&e基本上是A*,B*,D*类型,为什么它甚至会编译,并且使用这个属性是很好的实践吗?

代码语言:javascript
复制
#include <iostream>

using namespace std;

class A {
    public:
        virtual void f(){cout<<"A";};
};

class B :public A {
    public:
    virtual void f() {
        cout<<"B";
    }
};

class D : public B {
    public:
    virtual void f() {
        cout<<"D";
    }
};

class E : public D {
    public:
    virtual void f() {
        cout<<"E";
    }
};

void f(D *sth) {
    cout<<"D ptr"<<endl;
    sth->f();
}

void f(B *sth) {
    cout<<"B ptr"<<endl;
    sth->f();
}

void f(A *sth) {
    cout<<"A ptr"<<endl;
    sth->f();
}

int main() {
    E e;
    f(&e);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-05-26 01:10:44

我将尽我最大的努力来打破你的榜样:

代码语言:javascript
复制
int main() {
    E e;    // declare object of Class E
    f(&e);  // run f() function and pass it the address of E
}

好的,很简单--您声明了一个E类的对象,然后在它上运行了一个函数。现在全局f()函数已被重载三次,以接受指向D对象、B对象或A对象地址的指针。因为所有这些都在继承树的较高位置接受对象,所以任何对象都可以用于类E对象。编译器将为大多数派生类选择函数。在这种情况下,选择了void (D*某事物)函数。

代码语言:javascript
复制
void f(D *sth) {
    cout<<"D ptr"<<endl; // "D ptr" printed to screen
    sth->f();            // Take original pointer to class E object and 
                         // run its own class method f() on it
}

然后查看E的类定义,我们将看到为什么打印E:

代码语言:javascript
复制
class E : public D {
    public:
    virtual void f() {
        cout<<"E";
    }
};

如果要注释void (D*某事物)函数,则编译器将选择void (B*某事物)函数,从而输出"B ptr“和"E”。如果要注释掉A和B对象的全局f()函数,然后尝试在B对象上运行void (D*某某物),它将不会编译,因为编译器只能将对象转换到继承树上,而不能向下转换。

正如Phil1970所评论的那样,由于它依赖于具有继承树知识的全局函数,所以这种结构通常是不受欢迎的。

票数 0
EN

Stack Overflow用户

发布于 2016-05-26 01:16:49

它应该给你一个未定义的行为或模糊。不同的编译器版本可以提供不同的结果,所以最好不要依赖结果:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37449246

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档