无法从基类指针访问子类方法

时间:2018-08-01 20:45:31

标签: c++ c++11

不知道我的继承在这里出错了,但是当将子类实例存储在基类指针中时,我似乎只能访问基类的方法:

class Car
{
    public:
        Car():type("Car") {};
        Car(const char* t):type(t) {};
        void get_type() const { return this->type; };
    private:
        std::string type;
};

class Ford : public Car
{
    public:
        Ford():Car("Ford"), doors(4) {};
        Ford(int x):Car("Ford"), doors(x) {};
        void get_doors() const { return this->doors; };
    private:
        int doors;
};

int main()
{
    Car* c = nullptr;
    c = new Ford();
    c->get_doors(); // doesn't exist, only allows for get_type()
}

很有可能是滥用指针。我会承认C ++不是我的强项,所以我试图复制一个用Python编写的程序,该程序大量使用继承,但是它比用C ++编写的程序要简单得多,因为您没有明确使用Pointers and References(at是抽象级别。

2 个答案:

答案 0 :(得分:4)

Python方法是动态的 -本质上是纯对话式的Smalltalk。您向实例发送一条消息,如果它可以回答,则可以。

C ++不是那样的。它使用 static 类型。您已声明了类型为Car*的对象,因此a)它可以保存指向任何Car实例或Car子类型实例的指针,并且b)只能被告知去做Car可以去做的事情。

C ++也具有 virtual 方法。如果在Car中声明的方法是虚拟的,则可以在Car的子类(例如,在Ford中)实现。然后,在通过Car指针进行调用时,将调用该子类的实现。

答案 1 :(得分:1)

这正是应该发生的情况。 Car*指针仅使您可以看到Car个成员。尝试使用Ford*指针来查看Ford方法。要了解原因,请考虑您还有另一个源自Car的课程:

class Honda : public Car {
    // no get_doors() here
    void honk();
};

... 

Car* c = new Honda();
c->get_doors(); // What should happen here???

另一方面,如果您想让每个 Car拥有自己的门数,则可以做几件事:

您可以在基类中声明一个常量成员:

class Car {
public:
    Car(int num_doors) : m_doors(num_doors) {}

    int get_doors() const { return m_doors; }
private:
    const int m_doors;
}

class Ford : public Car {
    Ford() : Car(4) {} // Now every ford has 4 doors
}

class Honda : public Car {
    Honda() : Car(5) {} // and every honda has 5
}

您可以做的另一件事是在基类中声明一个虚函数,并在每个子类中覆盖该虚函数:

class Car {
public:
    virtual int num_doors() const = 0;
}

class Ford : public Car {
    int num_doors() const override { return 4; } // Now every ford has 4 doors
}

class Honda : public Car {
    int num_doors() const override { return 5; } // and every honda has 5
}