Effective C++原则

【001】视C++为一个语言联邦

            C++体系包括C、Object-Oriented(面向对象编程)、Template(模板)、STL(标准模板库)

【002】尽量使用Enum、const、inline代替#define
  • a.#define:在预编译阶段采用直接替代方式,不方便调试
  • b.const:修饰变量、函数、指针、引用、对象
  • c.inline:对于短小且调用频繁的函数可以声明为内联函数,提高效率
【003】切莫使用未初始化的变量或者对象
  • a.为内置类型进行手动初始化,C++不保证初始化他们
  • b.构造函数最好(或者一定)使用初始化列表进行初始化,而不是赋值进行初始化(提高效率)
  • c.成员变量初始化顺序为声明顺序,与初始化列表顺序无关
【005】了解C++默默产生哪些函数
  • a.当用户未声明构造函数、赋值、复制构造函数,在需要的情况下(也就是说并不一定会生成,只是在需要建立类对象)
  • b.编译器会为类生成默认的构造函数、复制函数、赋值函数
  • c.一旦用户声明上述函数,则编译器不再自动生成。
  • d.编译器自动生成的赋值、复制构造函数属于浅复制,当存在指针、引用成员变量时,会导致严重问题。
【006】若不需要编译器自动生成上述函数,应明确拒绝
  • a.方式-:用户自己声明赋值、复制构造函数,且权限设为private
  • b.方式二:定义Class UnCopy{
  • private:
  • UnCopy operator=(UnCopy &rhs);
  • }
【007】为多态基类定义Virtual析构函数
  • a.当采用多态形式 Base *pBase = new Derived();
  • b.若基类析构函数为virtual: delete pBase;//会调用子类的析构函数,不会产生内存泄漏
  • 若基类析构函数为non-virtual:delete pBase;//不会调用子类的析构函数,只能删除子类中基类成员部分,会产生内存泄漏
【008】别让异常逃离析构函数
  • a. try...catch捕获
【009】不要在构造函数中调用Virtual函数,会导致不可预期的错误
  • a.在子类构造函数未完成之前,其类型是不完整类型,因此在构造函数中调用virtual函数只会调用基类中virtual函数
【010】令operator=返回引用,链式编程
【011】在operator=中处理“自我复制”
  • class ClassName{
  • public:
  • //构造函数
  • .....
  • private:
  • char* str;

  • }
  • 方式一:ClassName& operator=(ClassName& const T){
  • if(*this==T){
  • return *this;
  • }else{
  • delete str;
  • str = T.str;
  • return *this;
  • //复制操作
  • }
  • }
  • 方式二:方式一:ClassName& operator=(ClassName& const T){
  • //保存旧值
  • char *oldStr = T.str;
  • delete str;
  • str = oldStr;
  • return *this;
  • }
【012】复制对象时,切莫忘记复制基类成员变量(复制函数中调用基类的复制函数)
【013】以对象管理资源(在对象析构函数中释放资源),避免资源泄漏
  • 例如:智能指针
  • auto_ptr<ClassName> pInt(new ClassName());
  • auto_ptr:底层实现调用delete ptr,不能应用于数组,不能复制
  • shared_ptr:底层实现引用计数,支持复制,资源可以共享
【014】在资源管理类中小心copying行为
  • 如上auto_ptr、shared_ptr行为
  • 浅复制和深复制的区别,内部含有指针时,只是简单复制指针,造成两个对象耦合,
  • 内部指针指向同一个对象,当一个对象消亡,调用析构函数释放内部指针指向的对象时,
  • 另一个对象的内部指针成为野指针,造成不可预期的错误
【015】在资源管理类中提供对原始资源的访问方式
  • 即是在资源管理类中提供接口,返回内部原始资源的指针或者引用
【016】成对使用new和delete。
  • 注意delete和delete[]区别
【017】以独立语句将new资源指针放入资源管理类(智能指针),防止产生异常
  • auto_ptr<ClassName> pInt(new ClassName());//有问题,当new ClassName()产生异常时,传入参数是null指针
  • ClassName *pClassName = new ClassName();
  • auto_ptr<ClassName> pInt(pClassName);//合理做法
【018】让接口能够被正确使用,不能被误用。
  • 做好异常值判断,即用户传入任何值都能获得应得的行为
【019】设计Class犹如设计Type
  • 考虑到各种异常输入
【020】用pass-by-reference取代pass-by-value
  • 对于一个类对象:传值意味着一次复制构造+一次析构函数的时间成本
  • 对于内置类型pass-by-value更合理
【021】必须返回对象时,别妄想返回reference
  • 局部对象在函数返回时消亡,返回引用则是无效引用
  • ClassName& function()
  • {
  • ClassName tt;
  • //do something;
  • return tt;
  • }//错误
【022】将成员变量设为private,提供统一接口,增强封装性
  • 定义setter和getter函数
  • 越少的“人”看到内部成员,则改动时影响越小
【023】宁以非成员、非友元函数取代成员函数
【024】若所有参数皆需类型转换,则采用非成员函数
  • 解决classValue*2和2*classValue问题
【025】考虑写出一个不抛出异常的Swap函数
【026】尽可能延后对象定义的时间(使用时再定义)
【027】尽量少做转型操作
  • const_cast:去除变量const属性
  • static_cast:隐式转型
  • dynamic_cast:向下转型
  • reinterpret_cast:任意转型,破坏性最大
【028】避免返回Handle指向对象内部成分
【029】为异常安全而努力是值得的
【030】透彻了解inline里里外外
  • 将大多数inline限制在小型被频繁调用的函数身上,这可使日后的调试更容易,也可使代码膨胀问题最小化,使程序的速度提升机会更大化
  • 不要只因为function template出现在头文件中,就将他们声明为inline
【031】将文件间的依存关系降到最低
【032】确定你的public继承塑造出is-a关系
【033】避免遮掩继承而来的名称
  • derived class内的名称会遮掩base class内的名称,在public继承下从来没有人希望如此
  • 为了让被遮掩的名称重见天日,可用using声明式或转交函数
【034】区分接口继承和实现继承
  • 声明一个纯虚函数目的是让子类只继承函数接口
  • 声明非纯虚函数目的是让子类继承该函数的接口和缺省实现
【035】考虑virtual函数以外的其他选择
【036】绝不重新定义继承而来的non-virtual函数
【037】绝不重新定义继承而来的缺省参数值
【038】通过组合构造出has-a关系
【039】明智而审慎使用private继承
【040】明智而审慎的使用多重继承
  • 多重继承带来对象布局不同,比单一继承复杂,他可能导致新的歧义性,以及对virtual继承的需要
  • virtual继承会增加大小、速度、初始化复杂度等等成本,如果virtual base class不带任何数据将是最具实用价值的情况
【041】了解隐式接口和编译器多态
  • classes和templates都支持接口和多态
  • class而言接口是显式的,以函数签名为中心,多态则是通过virtual函数发生于运行期
  • template参数而言,接口是隐式的,奠基于有效表达式,多态则是通过template具现化和函数重载解析发生于编译器
【042】了解typename的双重意义
  • template<class T>和template<typename T>意义相同
  • 请使用关键字typename表示嵌套丛书类型名称;但不得在base classlist内 以它作为base class修饰符
【043】学习处理模板化基类内的名称
【044】将于参数无关的代码抽离template
【045】运用成员函数模板接受所有兼容类型
【046】需要类型转换时请为模板定义非成员函数
【047】请使用traits class表现类型信息
【048】认识template元编程
【049】了解new-handler的行为
【050】了解new和delete的合理替换时机
【051】编写new和delete时需要固守常规




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值