《Effective C++》学习总结(条款31- 40)

本文详细探讨了C++编程中降低编译依赖性的策略,如接口与实现分离(pimpl idiom)、编译依赖最小化的设计原则,以及如何通过handle class和interface class降低耦合。同时,文章讲解了面向对象设计中的继承概念,如确定public继承表达is-a关系、避免名称遮掩、区分接口继承和实现继承、使用非虚拟接口(NVI)和策略模式等。此外,还强调了不应重新定义继承的non-virtual函数和缺省参数值,以及明智使用private继承和多重继承的重要性。
摘要由CSDN通过智能技术生成

条款31:将文件间的编译依存关系(compilation dependencies)降至最低

  • 对于C++类而言,如果它的头文件变了,那么所有这个类的对象所在的文件都要重编,但如果它的实现文件(cpp文件)变了,而头文件没有变(对外的接口不变),那么所有这个类的对象所在的文件都不会因之而重编
1.接口与实现分离(通过pimpl idiom的设计方式)——其实质在于以”声明的依存性“替换”定义的依存性“
  • 上述也是编译依存最小化的本质——现实中让头文件尽可能自我满足,万一做不到,则让它与其他文件内的声明式相依
2.编译依存最小化核心的设计策略:
  • 如果使用object references或object pointers可以完成任务,就不要用objects

  • 如果能够,以class声明式替换class定义式

  • 为声明式和定义式提供不同的头文件

3.基于上述策略的方式是——制作handle class(也就是通过pimpl idiom的设计方式)
  • 方法一:将它们的所有函数转交给相应的实现类(implementation classes)并交由后者完成实际工作

    • 在.h文件中用class 声明代替include头文件,把成员变量替换为指针的形式,此时任何接口类头文件产生的变化只会导致接口类头文件的变化而重新编译,以及Person实现文件由于include了接口类的头文件也要重新编译;而Person类头文件由于只使用了类的声明式,所以并不会重新编译,因此所有使用Person类的对象的文件也都不需要重新编译了,这样就大大降低了文件之间的编译依存关系
  • 方法二:令该类成为一种特殊的abstract base class(抽象基类),称为interface class(接口类)

    • 父类只提供虚方法,而将实现放置在子类中,再通过父类提供的一个特别的静态函数,生成子类对象,通过父类指针来进行操作;从而子类头文件的改动也不会导致使用该类的文件重新编译,因为用的是父类指针,客户include的是只是父类头文件。

    • 例子:

      std::tr1::shared_ptr<Person> Person::Create(const std::string& name,                    
                                                  const Date& birthday, 
                                                  const Address& addr)
      {
          return std::tr1::shared_ptr<Person>(new RealPerson(name, birthday, addr));
      }
      
4.handle class和interface class解除了接口和实现之间的耦合关系,从而降低了文件之间的编译依存性
5.使用上述的两个方法解除耦合有好处,那就是降低了代码的维护成本,但是也有缺点:
  • 前者的缺点是动态内存带来的额外开销
  • 后者的问题是virtual使用时vptr的性能损失
6.请记住:
  • 支持“编译依存最小化”的一帮构想是:相依于声明式,不要相依于定义式。基于此构想的两个手段是handle classes和interface classes
  • 程序库头文件应该以“完全且仅有声明式”(full and declaration-only forms)的形式存在。这种做法不论是设计templates都适用

 

第六章:继承与面向对象设计(Inheritance and Object-Oriented Design)

条款32:确定你的public继承塑模出is-a关系

1.以C++进行面向对象编程,最重要的一个规则就是:public inheritance(公开继承)是一种”is-a“的关系
2.请记住:
  • “public继承”意味着is-a的关系。适用于base classes身上的每一件事情一定也适用于derived classes身上,因为每一个derived class对象也都是一个base class对象

 

条款33:避免遮掩继承而来的名称

1.C++的名称遮掩规则所做的唯一事情就是:遮掩名称,至于名称是否有相同的类型࿰
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值