Effective C++

本文介绍了C++编程中的若干最佳实践,包括理解C++作为多重范型编程语言的特点,使用const、枚举和内联替代预处理器定义,确保对象初始化,避免在构造和析构过程中调用虚函数等内容。

条款01:视C++为一个语言联邦

多重范型编程语言(multiparadigm programming language)
  • 过程形式(procedural)
  • 面向对象形式(object_oriented)
  • 函数形式(functional)
  • 泛型形式(generic)
  • 元编程形式(metaprogramming)
次语言(sublanguage)
  • C
  • Object-Oriented-C++
  • TemplateC++
  • STL

条款02:尽量以const,enum,inline替换#define

class GamePlayer {
private:
    static const int NumTurns = 5;
    int scores[Numturns];
    ...
};
class GamePlayer {
private:
    enum { NumTurns = 5};
    int scores[Numturns];
    ...
};

条款03:尽可能使用const

char* p = greeting;             //non-const pointer,non-const data
const char* p = greeting;       //non-const pointer,const data
char* const p = greeting;       //const pointer,non-const data
const char* const p = greeting; //const pointer,const data
class TextBlock {
public:
    ...
    const char& operator[] (std::size_t position) const {
        return text[position];  //operator[] for const object
    }
    char& operator[] (std::size_t posotion) {
        return text[posiiton];  //operator[] for non-const object
    }
private:
    std::string text;
}
class TextBlock {
public:
    ...
    const char& operator[] (std::size_t position) const {
        ...
        return text[position];
    }
    char& operator[] (std::size_t posotion) {   //将op[]返回值的const转除
        return const_cast<char&>(               //为*this加上const
            static_cast<const TextBlock&>(* this)
            [position]                          //调用const op[]
        );
    }
    ...
};

条款04:确定对象被使用前已先被初始化

ABEntry::ABEntry(const std::string& name, const std::string& address,
    const std::list<PhoneNumber>& phones)
    :theNmae(name), theAddress(address),
    thePhones(phones), numTimesConsulted(0) {
    }
class FileSystem { ... };
FileSystem& tfs() {
    static FileSystem fs;
    return fs;
}
class Directory { ... };
Directory::Directory( params ) {
    ...
    std::size_t disks = tfs().numDisks();
    ...
}
Directory& tempDir() {
    static Directory td;
    return td;
}

条款05:了解C++默默编写并调用哪些函数

template<class T>
class NameObject {
public:
    NameObject(std::string& name, const T& value);
private:
    std::string& nameValue;
    const T objectValue;
};

条款06:若不想使用编译器自动生成的函数,就该明确拒绝

class UnCopyalbe {
protected:
    UnCopyalbe() {}
    ~UnCopyalbe() {}
private:
    UnCopyalbe(const UnCopyalbe&);
    UnCopyalbe& operate=(const UnCopyalbe&);
};
class HomeForSale: private UnCopyalbe {
    ...
};

条款07:为多态基类声明virtual析构函数

class TimeKepper {
public:
    TimeKepper();
    virtual ~TimeKepper();
    ...
};
TimeKepper* ptk = getTimeKeeper();
...
delete ptk;
class AWOV {
public:
    virtual ~AWOV() = 0;
};
AWOV::~AWOV() {}

条款08:别让异常逃离析构函数

class DBConnection {
public:
    ...
    static DBConnection create();
    void close();
};
class DBConn {
public:
    ...
    ~DBConn() {
        db.close();
    }
private:
    DBConnection db;
}
DBConn dbc(DBConnection::create());
class DBConn {
public:
    ...
    void close() {
        db.close();
        closed = true;
    }
    ~DBConn() {
        if (!closed) {
            try {   
                db.close();
            }
            catch(...) {
                ...
            }
        }
    }
private:
    DBConnection db;
    bool closed;
}

条款09:绝不在构造和析构过程中调用virtual函数

class Transaction {
public:
    explicit Transaction(const std::string& logInfo);
    void logTransaction(const std::string& logInfo) const;
    ...
};
Transaction::Transaction(const std::string& logInfo) {
    ...
    logTransaction(logInfo);
}
class BuyTransaction: public Transaction {
public:
    BuyTransaction(parameters)
    :Transaction(createLogString(parameters)) {
        ...
    }
    ...
private:
    strtic std::string createLogString(parameters);
};

条款10:令operator=返回一个reference to * this

class Bitmap {...};
class Widget {
    ...
private:
    Bitmap* pb;
};
Widget& Widget::operator=(const Widget& rhs) {
    Bitmap* pOrig = pb;
    pb = new Bitmap(*rhs.pb);
    delete pOrig;
    return * this;
}
class Widget {
    ...
    void swqp(Widget& rhs);
    ...
};
Widget& Widget::operator=(const Widget& rhs) {
    Widget temp(rhs);
    swap(temp);
    return * this;
}
Widget& Widget::operator=(Widget rhs) {
    swap(rhs);
    return * this;
}

条款12:复制对象时勿忘其每一个成分

PriorityCustomer::PriorityCustomer(const PriorityCustomer& rhs)
: Customer(rhs), priority(rhs.priority) {
    logCall("PriorityCustomer copy constructor");
}
PriorityCustomer& PriorityCustomer::operator=(const PriorityCustomer& rhs) {
    logCall("PriorityCustomer copy assignment operator");
    Customer::operator=(rhs);
    priority = rhs.priority;
    return * this;
}

条款13:以对象管理资源

void f() {
    std::suto_ptr<Investment> pInv(createInvestment()):
    ...
}
void f() {
    std::tr1::shared_ptr<Investment> pInv(createInvestment());
    ...
}

条款14:在资源管理中小心copying行为

class Lock {
public:
    explicit Lock(Mutex* pm): mutexPtr(pm. unlock) {
        lock(mutexPtr.get());
    }
private:
    std::trl::shared_ptr<Metux> mutexPtr;
};

条款15:在资源管理类中提供最原始资源的访问

条款16:成对使用new和delete时要采用相同形式

std::string* stringPtr1 = new std::string;
std::string* stringPtr2 = new std::string[100];
...
delete stringPtr1;
delete [] stringPtr2;

条款17:以独立语句将newed对象置入智能指针

int priority();
void processWidget(std::trl::shared_ptr<Widght> pw, int priority);
std::trl::shared_ptr<Widget> pw(new Widget);
processWidget(pw. priority());

条款18:让接口容易被正确使用,不易被误用

条款19:涉及class犹如设计type

条款20:宁以pass-by-reference-to-const替换pass-by-value

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值