effective c++阅读笔记

effective c++

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

1、C++高效编程守则视状况而变化,取决于使用C++哪一部分:

sublanguage(次语言):
C: blocks、statements、preproessor、built-in data types、arrays、pointers etc
Object-Oriented C++: class、encapsulation、inheritance、polymorphism、virtual etc
Template C++: programming paradigm (aka template metaprogramming, namely TMP)
STL: containers、iterators、algorithms、function objects

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

1、 尽量用编译器代替预处理器,编译器会做类型检查

const double AspectRatio = 1.6;  
const char* const authorName = "Tom"; // 常量指针常量     

2、注意:
1)尽量使用string替代char* : const string authorName(“Tom”);
2)为了将常量的作用域(scope)限制于class内,必须让他成为class的一个成员(member);而为确保此常量至多只有一份实体,必须让它成为一个static成员:

class GamePlayer{  
privatestatic: const int NumTurns = 5; // 常量声明式
    int scores[NumTurns];           // 使用该常量
}

3、如果不想让别人获得某个整形的pointer或refrence,可以使用enum(类似#define)

class GamePlayer{
private:
    enum{ NumTurns = 5 };
    int scores[NumTurns];
}

4、使用inline代替#define

#define max(a, b) f((a) > (b) ? (a) : (b)) 

即使给所有实参加括号,但仍然会发生不可预料的错误,如

int a = 5, b = 10;  
max(++ a, b);       // a 累加两次  
max(++ a, b + 10);  // a 累加一次

使用template inline代替上述宏定义:

template<typename T>
inline void max(const T& a, const T& b){
    f(a > b? a : b); 
}

结论

  • 对于单纯常量,最好以const或enums代替#define
  • 对于形似函数的宏(macros),最好改用inline函数替换#define

条款03:尽可能使用const

1、const如果出现在*左边,表示被指物是常量;如果在右边,表示指针自身是常量;如果在两边,表示被指物和指针都是常量。

const int* p = 1;       // aka int const* p = 1; non-const pointer, const data;
int* const p = 1;       // const pointer, non-const data;
const int* const p = 1; // const data, const pointer;

2、使用const修饰迭代器就像声明指针为const一样(aka T* const);若想要迭代器指向的内容不可改动,应使用const_iterator;

std::vector<int> vec;
const auto iter = vec.begin(); // aka T* const iter;
iter ++; 	// error !

auto citer = vec.cbegin(); 		// aka const T*; 
								// std::vector<int>::const_iterator
*citer = 10;	// error!

3、const可以修饰函数返回值,预防if(a * b = c)这种动作。

const Rational operator*(const Rational& lhs, const Rational& rhs);

4、成员函数是const

bitwise constness(physical constness) : 成员函数不可以更改对象内的任何一个bit,因此const成员函数不可以更改对象内任何non-static成员变量;但是在包含指针时结果可能不尽人意

class CTextBlock{
public:
	//inappropriate (but bitwise const) declaration of operator[]
	char& operator[](std::size_t position) __const__{	// 禁止更改非静态成员变量

	return p[position];
	}
private:
	char* p;
}

const CTextBlock cctb("Hello");	// declare constant object
char* pc = &cctb[0];	// call the const operator[] to get a pointer 
*pc = 'j';			// cctb = "jello" , still can change its content

__logical constness:__在观测者的角度不会改变成员的值

class CTextBlock{
public:
	...
	std::size_t length() const;
private:
	char* pText;
	std::size_t textLength; // last calculated length of textblock
	bool lengthIsValid;     // whetherlength is currently valid
}

std::size_t CTextBlock::length() const	
{
	if(!lengthIsValid){
		textLength = std::strlen(pText);	// cant assign to textLength
		lengthIsValid = true;		// lengthIsValid in a const member function
	}
	return textLength;
}

可以使用mutable 关键字来修饰其中需要改变的变量。如

mutable std::size_t textLength;
mutable bool lengthIsValid;

这两个变量时私有变量,不会暴漏给使用者,故这个程序在逻辑上是constness
5、在const和非const成员函数中避免代码复制,一些类中,const成员函数和non-const成员函数功能类似,在这两个函数中都要执行相同的代码,如:

class CTextBlock{
public:
	const char& operator[](std::size_t position)const
	{
		prepare();//准备
		return pText[position];
	}
	char& operator[](std::size_t position)
	{
		prepare();//准备
		return pText[position];
	}
	void prepare()const;//一些准备动作
	char * pText;
	int length;
};

如果两个方法处理逻辑差不多,可以是用类型转换,把non-const转换为const,再转换其返回值类型,是一个避免代码重复的安全方法

class CTextBlock{
public:
	const char& operator[](std::size_t position)const
	{
		prepare();//准备
		return pText[position];
	}
	char& operator[](std::size_t position)	// now just calls const op[]
	{
		return const_cast<char&>(	\		// cast away const on op[]'s return type
					static_cast<const CTextBlock&>(*this) \  // add const to *this'type	
					[position]);			// call const version of op[]
	}
	void prepare()const;//一些准备动作
	char * pText;
	int length;
};

但是,const的函数不能强制转化为非const的函数。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值