C ++中的多态(意外行为)

时间:2017-08-08 11:55:25

标签: c++ inheritance polymorphism virtual-functions

我有以下三个课程:

ionic run android -l -c -s

主:

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。你知道为什么吗?

3 个答案:

答案 0 :(得分:6)

  

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

这是你错的地方。在A中,您将doSomething()声明为virtual。这意味着它是implicitly marked virtual in classes that derive from it。因此doSomething()Bvirtual,这意味着您将致电C doSomething()

答案 1 :(得分:4)

原因是doSomething在班级A中被标记为虚拟。因此,它们仍然是BC中的虚拟,因为它们继承自A类。

由于此函数是虚拟,因此根据对象的实际类型(在您的情况下为C)调用它,并获得输出:I am C

答案 2 :(得分:0)

一旦标记为虚拟,它将在所有派生类中保持虚拟。

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

如果在doSomething()的C中省略了覆盖,则输出将如您所愿。

KR, Melle的