effective_C++

1. 将构造函数声明为__explicit__,以阻止它们被用来执行隐式类型转换;

class Rational{
    public:
	explicit Rational(int numerator = 0, int denominator = 1);
    const Rational operator+(const Rational& rhs) const;
    ...
};
Rational oneHalf(1, 2);
// 下式非法:2被禁止隐式转换为Rational类型
Rational result = oneHalf + 2; 

2. 按值传递内置类型,按址传递(pass by reference to const)用户自定义类型;

3. 尽量以const、enum、inline替换#define;

// 对于单纯常量,以const或enum替换#define
const int Size = 5;
enum {Size = 5};

4. 尽可能使用const;

ClassA operator*(ClassA lhs, ClassA rhs); // 不要采用这种方式!
// 令函数返回常量
const ClassA operator*(const ClassA& lhs, const ClassA& rhs);

5. 确定对象被使用前已先被初始化;

  1. 类构造函数使用成员列表初始化;
  2. 为内置对象手动初始化;
  3. 以local static对象替换non-local static对象(使用返回指向该对象的引用的函数,该non-local static对象在该函数内即为local static);

6. 若不想使用编译器自动生成的函数,可将相应的成员函数声明为private并且不予实现;

// 不使用copy构造函数和copy赋值操作符
class Home{
    // ...
    private:
	Home(const Home&);
	Home& operator=(const Home&);
};

7. 为多态基类声明virtual析构函数。

  1. 多态基类应该声明一个virtual析构函数。如果class带有任何virtual函数,就应该有一个virtual析构函数。
  2. 若类的设计目的不是作为基类使用,或不是为了具备多态性,就不该声明virtual析构函数。

8. 在__operator=__中处理“自我赋值”。

Home operator=(const Home& rhs){
    // 证同测试
    if (this == &rhs) return *this;
    ...
    return *this;
}

9. 为防止资源泄漏,使用RAII对象。

// 调用工厂函数返回对象指针
Investment* pInv = createInvestment();
...
delete pInv;
// 改用RAII class,如auto_ptr、tr1::shared_ptr
// RAII对象在构造函数中获得资源并在析构函数中释放资源
std::auto_ptr<Investment> pInv(createInvestment());
std::tr1::shared_ptr<Investment>pInv(createInvestment());

10. 使用non-member non-friend函数替换member函数

// 使用non-member函数并和class放于同一namespace中
namespace WebBrowserStuff{
    class WebBrowser {...};
    void clearBrowser(WebBrowser& wb);
}
// 若所有参数都需类型转换,应采用non-member函数
const Rational operator*(const Rational& lhs, const Rational& rhs);

10. 区分接口继承和实现继承

  • 纯虚函数只指定接口继承;
  • 虚函数指定接口及缺省实现的继承;
  • non-virtual函数指定接口及强制实现的继承(严禁在派生类中重定义);

11. 考虑virtual函数外的选择

/*	virtual函数是动态绑定的,但缺省参数是静态绑定的。
	可以使用“非虚函数接口”替代virtual函数:
	令基类的一个public非虚函数调用private虚函数,后者可被派生类重新定义;非虚函数指定缺省参数和接口,private虚函数负责实现。 */
class Shape{
    public:
    // public non-virtual interface
    void draw(int num = 1) const {
        doDraw(num);
    }
    ...
    private:
    // private virtual implementation
    virtual void doDraw(int num) const = 0;
};
class Rectangle: public Shape{
    public:
    ...
    private:
    // 不须指定缺省参数
    virtual void doDraw(int num) const;
};

12. 复合(composition)塑模has-a

/*
复合指一种类型的对象内含其他种类型的对象。常见的形式有“has a”和“is-implemented-in-terms-of”。
*/
// has-a
class Address {...};
class PhoneNumber {...};
class Person {
    public:
    ...
    private:
    string name;
    Address address;
   	PhoneNumber phonenumber;
};
// is-implemented-in-terms-of
// 根据std::list对象实现一个Set对象
template<class T>
class Set {
    public:
    void insert (const T &item);
    std::size_t size() const;
    private:
    std::list<T> rep; // 用来表述Set的数据
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值