《Effective C++》阅读笔记一:概述

一开始,C++只是在C的基础上加上了一些面向对象的特性。C++最初的名称C with Class正反映了这样一个事实。但随着时间的推移以及语言的发展成熟,C++变得更加大胆和开放,各种新的特性被加入,补充和完善。如今的C++已经是一个多重泛型编程语言,一个同时支持过程形式(procedural),面向对象形式(object-oriented),函数形式(functional)、泛型形式(generic)、元编程形式(metaprogramming)的强大语言。这些新的特性使得C++拥有自己的完整特性,包括指针,包括模板,包括标准库。

C++,包括C中的类似场景,有几点是每一位有志于从事C++开发的程序员都应该牢记的特性:声明,定义,初始化。

所谓的声明(declaration),是告诉编译器某个东西的名称和和类型,但略去细节。以下时一些常见的声明方式:
extern int x;
std::size_t numDigits(int num);
class Widget;

template<typename T>
class GraphNode;

定义(definition)的任务是提供编译器一些声明所遗漏的具体细节。对于不同对象(包括基本内置对象)而言,定义是编译器为此对象分配内存的地方。对函数或函数模板而言,定义提供了详细的代码细节。对类或类模板而言,定义列出了他们的具体成员。
int x;

std::size_t numDigits(int number)
{
	std::size_t digitSoFar = 1;
	while ( (number /= 10) != 0)
		++digitSoFar;
	return digitSoFar;
}

class Widget 
{
public:
	Widget();
	~Widget();
	...
};

template<typename T>
class GraphNode
{
public:
	GraphNode();
	~GraphNode();
	...
};

初始化(initialization)是给与对象赋初值的过程。内建对象赋初值直接进行,而由用户定义的自定义类型的对象,初始化由构造函数执行。该构造函数可能由用户自定义,也可能由系统自动调用默认无参构造函数完成。
class A
{
public:
	explicait A();		// 默认无参构造函数
	explicit A(int x =  0, bool b = true);	// 默认有参构造函数
}
上述explicit 关键字表示,这些构造寒素不能执行隐式类型转换(implicit type conversions),但可以用来进行显式类型转换。通常这是受到鼓励的。

另外,关于自定义对象的赋值问题,需要特别关注拷贝构造函数和赋值操作符(=)重载的问题:
class Widget
{
public:
	Widget();
	Widget(const Widget& rhs);
	Widget& operator=(Widget& rhs);
	~Widget();
	...
};

Widget w1;		// 默认构造函数
Widget w2(w1);		// 拷贝构造函数
w2 = w1;		// 复制操作符重载
Widget w3 = w1;		// 拷贝构造函数(why),w3赋值时,还没有创建出来,要先调用构造函数
...

bool hasAcceptableQuality(Widget w);
...
Widget wa;
if (hasAcceptableQuality(aw));		// 拷贝构造函数(why)同样,sw需要赋值给一个临时对象,这个临时对象也同样还没有创建出来,需要用构造函数创建
...
对于拷贝构造还是赋值操作符重载,虽然实际的结果总是类似的,但究竟是调用了哪个函数还是值得讨论一下。但其实其原则非常简单:凡是赋值的对象还没有创建,需要创建对象的,都是用拷贝构造函数;凡是对象已经存在,则调用赋值操作符重载函数。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值