effective C++笔记之条款39: 避免“向下转换”继承层次

  • 先看如下例子:

class Person {…};
class BankAccount
{
public:
         BankAccount(const Person *primaryOwner, const Person *jointOwner);
         virtual ~BankAccount();
         virtual void makeDeposit(double amount)= 0;
         virtual void makeWithdrawal(doubleamount) = 0;
         virtual double balance() const = 0;
         …
};
class SavingsAccount : public BankAccount
{
public:
        SavingsAccount(constPerson *primaryOwner, const Person *jointOwner);
         ~SavingsAccount();
         void creditInterest();   //给账户增加利息
                   …
 };

 假设为所有账户维持一个列表,通过list类模板实现。

         list<BankAccount*>allAccount;   //银行中所有账户

         现在准备写一段代码来遍历所有账户,为每个账户计算利息。如下所示代码:

         for(list<BankAccount*>::iterator p = allAccount.begin(); p != allAccounts.end();++p)

                  (*p)->creditInterest();  //错误

         因为creditInterest只是为SavingsAccount对象声明的,而不是BankAccount。

        

  • 向下转换:从一个基类指针到一个派生类指针。向下转换了继承的层次结构。
  •  通过向下转换可以得到通过编译,并正常运行。(static_cast<SavingsAccount *>(*p)->creditInterest();)但是对以后的扩充类难以维护。向下转换难看、容易导致错误,而且使得代码难于理解、升级和维护。
  •  向下转换可以通过如下两种方法消除:
  1.  最好的方法是将这种转换用虚函数调用来代替,同时,它可能对有些类不适用,所以要使这些类的每个虚函数成为一个空操作
  2. 加强类型约束,使得指针的声明类型和你所知道的真的指针类型之间没有出入。
  • 当不得不进行向下转换时,可以采用比原始转换更好的办法。这种方法称为“安全的向下转换”,通过dynamic_cast运算符来实现。当对一个指针使用dynamic_cast时,先尝试转换,如果成功(即指针的动态类型和正被转换的类型一致),就返回新类型的合法指针;如果dynamic_cast失败,返回空指针。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值