c++ 的多态性和继承问题

问题描述 投票:0回答:1

我不明白为什么会打印这段代码

E::n() 
A::m() 
E::j()

如果我跑步

(p4->n()).m();
#include <iostream>

using namespace std;

class A{
    public:
        A() {cout << "A() ";}
        virtual ~A() {cout << "~A() ";}
        virtual const A* j() {cout << "A::j() "; return this;}
        virtual void k() {cout << "A::k() "; m();}
        void m() {cout << "A::m() "; j();}
};

class B: virtual public A{
    public:
        B() {cout << "B() ";}
        virtual ~B() {cout << "~B() ";}
        virtual void g() const{cout << "B::g() ";}
        virtual const B* j() {cout << "B::j() "; n(); return this;}
        void k() {cout << "B::k() "; j(); m();}
        void m() {cout << "B::m() "; g(); j();}
        virtual A& n() {cout << "B::n() "; return *this;}
};

class C: virtual public B{
    public:
        C() {cout << "C() ";}
        ~C() {cout << "~C() ";}
        void g() const{cout << "C::g() ";}
        void k() override{cout << "C::k() "; B::n();}
        virtual void m() {cout << "C::m() "; g(); j();}
        B& n() override{cout << "C::n() "; return *this;}
};

class D: virtual public B{
    public:
        D() {cout << "D() ";}
        ~D() {cout << "~D() ";}
        virtual void g() {cout << "D::g() ";}
        const B* j() {cout << "D::j() "; return this;}
        void k() const {cout << "D::k() "; k();}
        void m() {cout << "D::m() "; g(); j();}
};

class E: public C, public D{
    public:
        E() {cout << "E() ";}
        ~E() {cout << "~E() ";}
        E(const E& x) {cout << "Ec ";}
        virtual void g() const{cout << "E::g() ";}
        const E* j() {cout << "E::j() "; return this;}
        void m() {cout << "E::m() "; g(); j();}
        D& n() final{cout << "E::n() "; return *this;}
};

A* p1 = new E(); B* p2 = new C(); A* p3 = new D(); B* p4 = new E(); 
const A* p5 = new D(); const B* p6 = new E(); const E* p7 = new E();

焦点在 A::m() 上,为什么它不打印 E::n() 呢? M 方法在 C 类中被标记为虚拟方法。我错过了什么吗?

c++ inheritance polymorphism
1个回答
0
投票

p4
是一个
B*
,所以
p4->n()
在调用
B
时使用
n
的接口。

B::n
返回一个
A*
,因此
(p4->n())->m()
在调用
A
时使用
m
的接口。

A::m
不是虚拟的,因此调用不依赖于
*p4
的运行时类型。

© www.soinside.com 2019 - 2024. All rights reserved.