不知道我的继承在这里出错了,但是当将子类实例存储在基类指针中时,我似乎只能访问基类的方法:
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是抽象级别。
答案 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
}