本書介紹
本書的作者是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)第一遍可能讀不懂,沒關係,硬着頭皮看下去,然後再回頭看前面不懂的地方,如果還不懂,但是對於後面的理解沒有太大的影像,那就略過,如果跟後面知識點的理解關係很大,那就只能多讀幾遍了。
小結
之後會再讀一遍,也可能不止一遍,重點就在自己之前沒讀懂的地方啦。學習嘛,無非就是看看書,自己思考思考,然後在工作中一點點實踐,然後再回頭看看書,如此循環往復,以前不懂的地方可能就會有一些突破,懂的地方也可能會有新的理解。這就是一個學而思、思而學的過程,慢慢的內化成自己的知識。