zoukankan      html  css  js  c++  java
  • Effective C++ 学习笔记:关于继承

    决定用继承前,我们要考虑几个问题:

    1. 是否真的需要使用继承,还是应该用复合?

    继承表达的是is-a关系,派生类应该和父类有相同的行为。

    复合表达的是has-a关系,只需要复用子类的实现,而不需要子类的接口。

    2. 是否需要多继承?

    单继承的层次更为清晰,多继承则会引入更多的复杂性,使用的时候应该谨慎。

    多继承会导致变量存在多份的现象,避免的方法是使用virtual进行继承。

    多继承也有合理应用的场合,如:使用public方式从一个类继承接口,同时用private方式从另一个类继承实现。

    3. 继承的时候,用private、还是public?

    private继承方式表达的是implemented-in-term-of,用于从一个类继承实现。

    如果需要访问父类的protected类型成员,又不希望继承接口,就可以用private类型的继承。

    4. 需要继承什么,接口还是实现?

    定义pure virtual 函数,继承的是接口。pure virtual函数要求派生类必须提供实现。容易让人忽略的是,pure virtual函数也是可以有实现的。利用这个特性,我们可以定义接口,同时提供默认的实现。派生类中可以根据需要来调用默认的实现。

    定义impure virtual 函数,继承的是接口,但是提供了默认的行为。这样默认的行为可能会带来麻烦,因为用户可能并不知道会有这种默认的行为。如果想提供默认的行为,又需要用户明确的调用,可以采用pure virtual函数。

    定义 non-virtual 函数,继承的是实现,而且是不希望被重新定义的实现。

    在派生类中,我们需要注意以下几点:

    1. Name hiding

    对non-virtual函数,如果在派生类中提供了新的定义,父类中所有同名函数的定义都会被隐藏。

    派生类和父类可以理解为不同的作用域,父类的作用域在外,子类的作用域在内,内层作用域中定义的符号将会隐藏外层作用域中定义的同名符号。

    如果需要父类中的定义,可以使用using声明。

    2. 对virtual函数的默认参数,采用的是静态联编

    如果C++采用动态机制,需要比较大的开销,所以没有提供动态联编机制。

    3. 对非virtual函数,不应该重新定义

    重新定义会隐藏父类中的定义,导致父类和子类行为的不一致,这违背了is-a关系。

  • 相关阅读:
    sudo killall -9 php
    php 读取Excel内容时 对时间的值进行格式化处理
    执行Git命令时出现各种 SSL certificate problem 的解决办法
    git 强制拉取更新,本地修改
    PHP:如何合并多维数组中的子数组
    hibernate.validator 与 jackson
    jackson实体转json时 为NULL不参加序列化的汇总
    application.yml 增加数据库连接,重启日志卡死
    logback学习
    注解@Slf4j
  • 原文地址:https://www.cnblogs.com/weichsel/p/1870858.html
Copyright © 2011-2022 走看看