版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38126105/article/details/84503596
-
第一条:视C++为一个语言联邦
该条款的理解是,把c++看成一个由相关语言组成的联邦,而非单一的语言,在运用某个次语言的时候,应该遵守各个次语言的约定和规则,保证其简单,直观易懂。
c++次语言有以下四种:
C语言 c++是C语言的超集
Object-Oriented C++ 古典c++,即面向对象设计之古典规则在c++上最直接的实施。
Template c++ 泛型编程(很少被项目大量使用,难度)
STL STL是Template C++中特殊的一个。 -
第二条:尽量以const、enum、inline替换 #define
对于单纯常量,最好以const对象或enum替换define
对于形似函数的宏,最好用inline函数来替换宏 -
第三条:尽可能使用const
对于const的使用,可以参考const的使用
const的时候,可以保证程序的健壮性。需要注意的是在c++11中新增了一个关键字constexpr,这个关键字和const的区别是,const表示的是程序在运行期的不可修改属性,而constexpr可以表示在编译期间的不可修改属性。 -
第四条:确定对象被使用前已被初始化
该条款的意思一个对象的生成必须遵循RAII,即构造即初始化,所有的对象在生成时,其中的成员必须在构造中进行初始化。推荐使用初始化列表进行初始化,这比在构造函数中进行初始化,少了数据的拷贝。 -
第五条:了解c++默默编写并调用了哪些函数
该条款的意思是一个空类中,编译器会为该类生成以下几个函数:默认构造函数,默认拷贝函数,默认析构函数,默认operator=函数,在c++11之后,还有一个默认移动构造函数
- 第六条:若不想使用编译器自动生成的函数,就该明确拒绝
该条款的意思是,如果不想使用条款5默认的函数,就应该进行明确的拒绝。在c++11以前,可以将上述函数只声明而不是实现。在c++之后,可以使用delete进行明确的拒绝。 - 第七条:为多态基类声明virtual析构函数
该条款防止,当一个new出来的子类地址赋值给基类指针是,假如基类的析构函数不是virtual函数,则会导致子类的析构函数不会被调用,从而导致内存泄露。 - 第八条:别让异常逃离析构函数
不能在析构函数中抛出异常。个人建议尽量不要使用抛出c++异常,而是在出问题的地方,将异常情况解决或者记录,而不是抛出。 - 第九条:决不再构造和析构函数过程中调用virtual函数
在构造函数或者析构函数中调用virtual函数,有可能导致不可预期的行为发生,所以绝不应该在析构函数和构造函数中调用virtual函数。 - 第十条:令operator=返回一个reference to *this
该协议适用于所用的+=,-=等操作符
#include <iostream>
using namespace std;
//const 替换 #define
//#define PI 3.1415926
const double Pi = 3.1415926;
//enum 替换 #define
//#define NumTurns 5
class GamePlayer
{
public:
GamePlayer() { m_scores[NumTurns] = { 0 }; }
private:
enum {
NumTurns = 5
};
int m_scores[NumTurns];
};
//以inline 替换 #define
template<typename T>
inline const T& callWithMax(const T& a, const T& b)
{
return a > b ? a : b;
}
class Student
{
public:
Student(int age):m_age(age) {}
~Student() {}
private:
Student(const Student&) = delete; // c++11之后,推荐
//Student& operator=(const Student& rhs);//c++11之前,只声明,不实现
//条款10
Student& operator=(const Student& rhs)
{
if (this == &rhs)
{
return *this;
}
m_age = rhs.m_age;
return *this;
}
int m_age;
};