了解 C++ 中的继承和多态性

Posted

技术标签:

【中文标题】了解 C++ 中的继承和多态性【英文标题】:Understanding inheritence and polymorphism in C++ 【发布时间】:2018-02-28 18:28:46 【问题描述】:

假设我们有以下继承类。

class A

public:
    void virtual show()
    
        cout << "I am A\n";
    
;

class B:public A

public:
    void show()
    
        cout << "I am B\n";
    
;

class C:public B

public:
    void show()
    
        cout << "I am C\n";
    
;

int main()

    A *obj = new C();
    obj->show();

    return 0;

不创建任何其他对象,如何调用B类的show()函数???

我知道的一种方法是将 C 类中的 show() 修改为,

void show()

    B::show();
    cout << "I am c\n";

这将首先调用 B 的 show 函数,然后打印“I am C”。但我根本不希望 C 中的 show() 被执行。我希望 B 的 show() 直接执行。

有可能吗?我们可以使用铸造或其他东西来做到这一点吗?

请记住,除了已经创建的对象(即 main() 中的 C)之外,我不允许创建任何其他对象。 今天面试时被问到这个问题。

谢谢!

【问题讨论】:

只要在C班拿出表演,你就可以得到B的表演 没有任何迹象表明objB,这意味着您无法知道它有void B::show()。如果你知道你需要obj 是一种B,那么它应该是一个指向B 的指针。这似乎是一个设计错误。 “被直接执行”是什么意思?它不会打印“我是 C”,或者它必须完全绕过 C::show() 调用而只调用 B::show()? 我仍然对目的感到困惑。不假设继承链中有B,必须对其进行测试,这意味着类似于B *bptr = dynamic_cast&lt;B*&gt;(obj); if (bptr) bptr-&gt;B::show();。如果您可以假设 B 被楔入某处,那么它会变得相当容易。 @MuzahirHussain 如果在采访中被问到这个问题,我会首先问“为什么?”。似乎问题是要求实现设计错误的解决方案,而正确的解决方案是修复设计,而不是实现。 【参考方案1】:

您可以通过指定类来强制静态调度:

int main()

    A *obj = new C();
    static_cast<B*>(obj)->B::show();

    return 0;

但是如果你想使用这个方法,你必须确定该对象确实是一个B实例,否则它是未定义的行为。

【讨论】:

这假设我们知道 objB 的一种。在这种情况下很清楚,但它并不普遍适用。 我认为它不需要是通用的,只需在这种特定情况下工作。另外,你不能只做obj-&gt;B::show() 并完全跳过static_cast 吗? @Daniel obj 是一个A* 并且A 没有void B::show(),即使在这种情况下动态类型会有它。 @FrançoisAndrieux 我在答案中添加了一些额外的注释。我认为没有通用的方法可以做到这一点。 @liliscent 你可能会写if(B *b = dynamic_cast&lt;B*&gt;(obj)) b-&gt;B::show(),只有当obj 是B 或更高时才会执行

以上是关于了解 C++ 中的继承和多态性的主要内容,如果未能解决你的问题,请参考以下文章

C++ 封装,继承,多态总结

深入了解C++ (13) | 走近vtprvtbl,揭秘动态多态

C++多态

C++多态

C++之多态总结(多态的定义及实现,抽象类,多态原理,单继承,多继承中的虚函数表)

C++——多态