【问题标题】:Polymorphism in C++ (unexpected behaviour) [duplicate]C ++中的多态性(意外行为)[重复]
【发布时间】:2018-01-15 23:42:04
【问题描述】:

我有以下三个课程:

class A
{
private:
    std::string device;
public:
    std::string getDeviceType() { return device; };
    void setDeviceType(std::string device) { device = device; };
    virtual void doSomething() = 0;
    virtual void doSomething2() = 0;
};

class B: public A
{
    private:
    public:
        B(){ ; };
        virtual ~B(){ ; };
        void doSomething() { std::cout << "I am usual B" << std::endl; };
        void virtual doSomething2() { std::cout << "I am usual B" << std::endl; };
};

class C : public B
{
private:
public:
    C(){ ; };
    ~C(){ ; };
    void doSomething() { std::cout << "I am C" << std::endl; };
    void doSomething2() { std::cout << "I am C" << std::endl; };
};

主要:

B *myHandler = new C();
myHandler->doSomething();
myHandler->doSomething2();

但输出不如预期,我的预期输出是I am usual B,然后是I am C,因为doSomething()B 类的非虚拟成员。但真正的输出是I am C,然后是I am C。你知道为什么吗?

【问题讨论】:

  • [OT] { device = device; } 应该是 { this-&gt;device = device; },或者使用不同的名称。
  • 被覆盖的方法保持虚拟;由于A::doSomething 是,B::doSomethingC::doSomething 也是,不管关键字virtual 在声明中是否重复。

标签: c++ inheritance polymorphism virtual-functions


【解决方案1】:

一旦标记为虚拟,它在所有派生类中仍然是虚拟的。

在 C 中,您覆盖了 doSomething() 和 doSomething2()。您实例化 C,因此在这两种情况下都会调用 C 的方法。

如果您在 C 中省略了 doSomething() 的覆盖,则输出将与您预期的一样。

韩国, 梅勒

【讨论】:

    【解决方案2】:

    原因是doSomething 在类A 中被标记为虚拟。所以它在BC 类中保持虚拟,因为它们继承自类A

    由于这个函数是虚拟的,它是根据对象的真实类型调用的,在你的例子中是C,你会得到输出:I am C

    【讨论】:

      【解决方案3】:

      因为 doSomething() 是 B 类的非虚拟成员

      这是你误会的地方。在A 中,您将doSomething() 声明为virtual。这意味着它是implicitly marked virtual in classes that derive from it。所以doSomething() 中的Bvirtual,这意味着你将调用CdoSomething()

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-03
        • 1970-01-01
        • 2015-12-30
        • 2019-12-31
        • 1970-01-01
        • 2014-09-25
        • 1970-01-01
        • 2012-01-01
        相关资源
        最近更新 更多