1)您的函数都不是虚拟的,因此派生类不能正确覆盖任何函数。
2) Account joe(100) 创建 Account 类的实例,而不是 SavingsAccount 类的实例。如果您想在 joe 上调用 calculateInterest,则 joe 需要是一个 SavingsAccount。Account、SavingsAccount 和 CheckingAccount 仍然是它们自己独特的类。SavingsAccount 和 CheckingAccount 继承 Account 的数据和接口,但 Account 不继承它们的数据和接口。
3)如果您想将 joe 实例化为 SavingsAccount 但将其存储并视为帐户,那么您需要创建指向 Account 的指针并将其向上转换,但如果您正在处理它,您将无法访问 SavingsAccount 函数就像一个帐户。在这种情况下,您需要将 calculateInterest 移至 Account(如果需要,将其设为纯虚拟),然后在 SavingsAccount 中覆盖它。
class Account
{
// Add this to your Account class
virtual double calculateInterest() = 0;
};
class SavingsAccount : public Account
{
// Add this to your SavingsAccount class
double calculateInterest() override;
};
然后将 joe 创建为 SavingsAccount,但将其视为帐户:
SavingsAccount joe(100);
Account* pJoe = &joe;
double val = joe->calculateInterest(); // calculateInterest is available from Account, but because it's virtual, it calls the one from SavingsAccount.
如果你不想强制所有派生类实现这个功能,那么你真的需要在这里重新考虑你的整个设计。在任何情况下,解决它的一种廉价方法是使其非纯(从声明中删除 = 0,但保留虚拟)并提供返回一些默认值的默认实现。
这是一个例子:
class Account
{
// Add this
virtual double calculateInterest() { return 0.0; }
};
class SavingsAccount : public Account
{
// Add this
double calculateInterest() override; // and use your existing implementation
};
现在,如果您对 SavingsAccount 调用 calculateInterest,它将返回 SavingsAccount 的返回值。如果您在 CheckingAccount 上调用 calculateInterest,它将返回 Account 提供的默认实现,即 0.0。如果您对指向 SavingsAccount 实例的 Account* 指针调用 calculateInterest,它将返回 SavingsAccount 的返回值,因为它是虚拟的。