C++书籍阅读系列:《Essential C++》初读

本书介绍

本书的作者是Stanley B.Lippman,也是《C++ primer》的作者,我看的是侯捷老师翻译的中文版。相对于《C++ primer》的大部头,这本书可以说是短小精悍了,除去附录就只有200页左右了。但是个人觉得涵盖的知识点还是不太容易理解的,比如泛型编程和类模板章节。

自我收获和不足

本书总共分7个章节。

第一章(C++编程基础)、第二章(面向过程的编程风格)

算是很基础的东西,理解起来没什么难度,算是对C++基础的复习,所以有基础的同学应该看的很快。
对我来说读这一部分的收获就是重新理解static关键字、inline内联函数、函数指针。

第三章(泛型编程风格)

主要就是介绍STL中的容器(vector、list、set、map),以及作用于这些容器的泛型算法,容器一般都是直接拿来用,这章则更偏向于底层的介绍,说实话除了迭代器有了点深入的理解外,其他还是不太懂。

第四章(基于对象的编程风格)、第五章(面向对象的编程风格)

这两章可以说是我初读本书收获最大的部分,其实很大一部分我写的代码都是基于对象的编程风格,比如最多写几个类,封装几个函数,给其他类调用,最多写个类之间的继承,类之间仅仅是"is-a-kind-of"的关系。这种是基于对象(object-based)的编程。
那到底什么才是面向对象的编程呢?书中的解释是:面向对象编程的两个主要特性是:继承(inheritance)和多态(polymorphism)。继承不用多说,很容易理解 ,就是让我们可以定义一些相互关联的类,并共享共同的接口。那么多态呢?书里说多态则让我们得以用一种与类型无关(type-independent)的方式来操作这些类对象,看完后面的例子,其实就是我们使用派生类的时候,是让基类的指针指向派生类的对象。这是面向对象的动态绑定(dynamic binding)机制,需要用到虚函数来实现。借用书中图书馆的例子来说明一下。大致结构是基类LibMat、派生类Book、Book的派生类AudioBook。

#include <iostream>
#include <stdlib.h>
#include <string>
using namespace std;

class LibMat
{
public:
	LibMat();
	virtual ~LibMat();
	virtual void print() const
	{
		cout << "父类LibMat的print()函数被调用\n";
	}
};

LibMat::LibMat()
{
	cout << "父类LibMat的默认构造函数被调用!\n";
}

LibMat::~LibMat()
{
	cout << "父类LibMat的默认析构函数被调用!\n";
}

class Book:public LibMat
{
public:
	Book(const string &title,const string &author)
		:_title(title),_author(author)
	{
		cout << "Book::Book(" <<_title << "," << _author << ") 构造函数!\n";
	}
	virtual ~Book()
	{
		cout << "Book::~Book() 析构!\n";
	}

	virtual void print() const{
		cout << "Book::print() --I am a Book object!\n"
			<< "My title is:" << _title << '\n'
			<< "My author is:" << _author << endl;
	}

	const string title() const { return _title; }
	const string author() const { return _author;}

protected:
	string _title;
	string _author;
};

class AudioBook:public Book
{
public:
	AudioBook(const string &title,const string &author,const string &narrator)
		:Book(title,author),_narrator(narrator)
	{
		cout << "AudiBook::AudiBook(" << _title
			<< "," << _author
			<< "," << _narrator
			<< ") construcor\n";
	}

	~AudioBook()
	{
		cout << "AudioBook::~AudiBook() destructor!\n";
	}

	virtual void print() const{
		cout << "AudioBook::print() --I am an AudiBook object!\n"
			<< "My title is: " << _title << '\n'
			<< "My author is:" << _author << '\n'
			<< "My narrator is:" << _narrator << endl;
	}

	const string& narrator()const { return _narrator; }

protected:
	string _narrator;
};

可以看到每个类都有一个print()函数,用来输出一些基本信息,基类LibMat的print打印一条语句,表明是基类的print被调用了,Book类的print打印的是书名和作者,AudioBook类打印的是书名、作者和朗读者。下面看看用法
假设我定义一个函数print()用来调用这些类,print()的参数是LibMat类的一个对象。

void print(const LibMat &mat)
{
	cout << "在全局print()函数中打印mat对象的print函数!\n";

	mat.print();
}

int main()
{
   	cout << "\n" << "Createing a LibMat object to print()\n";
   	LibMat libmat;
   	print(libmat);
}

第一次我调用基类LibMat,可以看到基类的print()被正常调用。

第二次我调用Book类,但是print(const LibMat &mat)的定义还是不变。

int main()
{
   	//cout << "\n" << "Createing a LibMat object to print()\n";
   	//LibMat libmat;
   	//print(libmat);
 
     cout << "\n" << "Createing a Book object to print()\n";
     Book b("The Castle", "Franz Kafka");
     print(b);
}
可以看到, 我们并没有把非成员函数改成print(const Book &mat),但是程序还是正确调用了Book类的print()函数,输出了书名和作者。

第三次我调用AudioBook,print(const LibMat &mat)的定义还是不变。

int main()
{
   	//cout << "\n" << "Createing a LibMat object to print()\n";
   	//LibMat libmat;
   	//print(libmat);
 
     	//cout << "\n" << "Createing a Book object to print()\n";
     	//Book b("The Castle", "Franz Kafka");
     	//print(b);
// 
 	cout << "\n" << "Createing a AudioBook object to print()\n";
 	AudioBook ab("The Castle", "Franz Kafka","Kenneth Meyer");
 	print(ab);
}
同理, 我们不用把非成员函数改成print(const AudioBook &mat),也能得到正确的输出结果。

这就是本节一开始提到的多态则让我们得以用一种与类型无关(type-independent)的方式来操作这些类对象

这一章的小建议,读的时候可以反复读几遍,第一节的概念一开始看起来可能有点抽象,等看完后面的代码再回头看概念会有新的理解。

第六章(以template进行编程)

这一章看的时候真的很头大,反复读了好几遍还是没怎么看懂,特别是类模板的部分,我真的是大声读出来的,因为看着看着思维就飘了。然而还是没怎么看懂。只能作为遗留,下次再看了。

第七章(异常处理)

这一章很简短,讲的就是程序的异常捕捉处理机制,算是很常见的用法,没理解的地方是局部资源管理。

读者建议

不建议初学者使用,否则会看的一头雾水。即使有一定C++基础的同学也要慎重,就我读下来的感觉是,逻辑上跟一般的理解方式不同,比如有很多知识点直接拿来用,然后在后面的章节才会有详细解释,这就需要我们再跳回之前的地方再细看,也就是说需要我们前后比对着看,很多情况下第一遍看是一头雾水的,莫名其妙来段代码就开始讲。所以给想学习这本书的同学两点建议:
(1)最好使用纸质书,这样前后翻阅起来方便。当然也可能是我个人用不惯电子书看这类技术类的书籍。
(2)第一遍可能读不懂,没关系,硬着头皮看下去,然后再回头看前面不懂的地方,如果还不懂,但是对于后面的理解没有太大的影像,那就略过,如果跟后面知识点的理解关系很大,那就只能多读几遍了。

小结

之后会再读一遍,也可能不止一遍,重点就在自己之前没读懂的地方啦。学习嘛,无非就是看看书,自己思考思考,然后在工作中一点点实践,然后再回头看看书,如此循环往复,以前不懂的地方可能就会有一些突破,懂的地方也可能会有新的理解。这就是一个学而思、思而学的过程,慢慢的内化成自己的知识。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GHZhao_GIS_RS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值