zoukankan      html  css  js  c++  java
  • Effective C++ 第四章

    4. Designs and Declarations 设计与声明

    18: Make interfaces easy to use correctly and hard to use incorrectly.

    让接口容易被正确使用,不易被误用

    促进正确使用:

    • 保持接口的一致性,如STL容器都有一个名为size的成员函数
    • 与内置类型的行为兼容

    防止错误使用:

    • 建立新类型、限制类型上的操作,如不直接返回指针,而是返回智能指针,避免客户忘记delete

    • 束缚对象值

      导入 外覆类型(wrapper types)区分年、月、日

      Date d(Month::Mar(), Day(30), Year(1995));

    19:Treat class design as type design.

    设计class犹如设计type

    设计class需要考虑的问题:

    • 新type的对象如何被创建和销毁(第八章)

      构造函数、析构函数、内存分配函数和释放函数

    • 对象的初始化和赋值有什么差别(条款4)

      构造函数和赋值操作符

    • 以值传递如何实现

    • 新type的合法值

    • 是否需要继承(条款34、36)

    • 类型转换(条款15)

    • 合法的操作符(条款23、24、46)

    • 成员变量、成员函数的访问控制

    • 未声明接口(条款29)

    • class or class template

    • 是否需要新的type,或者增加非成员函数即可

    20: Prefer pass-by-reference-to-const to pass-by-value.

    • 传递对象给函数参数,pass-by-value会增加调用构造函数和析构函数的成本,引用传递可以避免

    • const类型,避免对原始对象的修改

    • 可以避免切割(slicing)问题:

      派生类对象传递给函数参数的基类对象,派生类的特化性质会被切割掉,只剩下基类对象

      引用传递可以实现多态,解决切割问题

    • 例外:

      内置类型、STL的迭代器、函数对象

    21: Don't try to return a reference when you must return an object.

    必须返回对象时,别妄想返回其reference

    • 不要返回指向局部的、堆上的或static的对象的指针/引用
    • 直接返回对象,交给编译器优化

    有理数乘法的正确实现版本

    inline const Rational operator*(const Rational& a, const Rational& b) {
    	return Rational(a.n*b.n, a.d*b.d);
    }
    

    22: Declare data members private.

    将成员变量声明为private

    pirvate的成员变量,可以

    • 划分访问控制
    • 实现封装,给客户提供一致性的函数接口
    • 声明为protected的变量,修改或取消同样会引发所有继承类的改变
    • 封装的角度,只有两种访问权限:private和其他

    23: Prefer non-member non-friend functions to member functions.

    24: Declare non-member functions when type conversions should apply to all parameters.

    若所有的参数都需要类型转换,请为此采用non-member函数

    要使下面的代码通过编译:

    class Rational {
    public:
        Rational(int numerator=0, int denominator=1); // 构造函数不为explicit,允许int隐式转换为Rational
        int numerator() const;
        int denominator() const;
    private:
        ...
    };
    
    Rational a(1, 4);
    Rational result;
    result = a * 2;
    result = 2 * a;
    

    有理数乘法应该设计为non-member:

    const Rational operator*(const Rational& a, const Rational& b) {
        return (a.numerator()*b.numerator(), a.denominator()*b.denominator());
    }
    

    可以避免fiend函数就该避免,这里不需要设计成为friend函数

    25: Consider support for a non-throwing swap.

    考虑写出一个不抛异常的swap函数

  • 相关阅读:
    lvs+nginx负载均衡
    数据库读写分离、分表分库——用Mycat
    RocketMQ最佳实战
    几个常用类
    Future复习笔记
    线程池复习笔记
    HashMap 和 ConcurrentHashMap比较
    HTTP长连接和短连接(转)
    咨询
    RocketMQ 问题汇总
  • 原文地址:https://www.cnblogs.com/izcat/p/13708540.html
Copyright © 2011-2022 走看看