譯自Deep C (and C++) by Olve Maudal and Jon Jagger,本身半桶水不到,如果哪位網友發現有錯,留言指出吧:)
總結一下第三講,我們可以知道,相對於第一位候選者,第二位候選者在以下幾個方面有更深的認識:
1、 C與C++的聯系;
2、 多態方面的技術;
3、 如何正確的初始化一個對象;
4、 Rule of three;
5、 操作符new[]與操作符delete[]方面的知識;
6、 常用的命名約定。
接下來,我們將分享一下幾個方面的知識:
1、 對象的生命周期;
2、 Rule of three;
3、 虛函數表。
先來看,恰當地進行對象初始化。賦值與初始化是不一樣的。來看這段代碼的輸出:
struct A
{
A() { puts("A()"); }
A(int v) { puts("A(int)"); }
~A() { puts("~A()"); }
};
struct X
{
X(int v) { a = v; }
X(long v):a(v) { }
A a;
};
int main()
{
puts("bad style");
{
X slow(int(2));
}
puts("good style");
{
X fast(long(2));
}
}
代碼輸出為:
bad style
A()
A(int)
~A()
~A()
good style
A(int)
~A()
再看看對象的生命周期:
C++的一個基本原理是:對象消亡時候需要采取的操作,正好是對象創建時候所采取操作的逆操作。
看下面的代碼:
struct A
{
A() { puts("A()"); }
~A() { puts("~A()"); }
};
struct B
{
B() { puts("B()"); }
~B() { puts("~B()"); }
};
struct C
{
A a;
B b;
};
int main()
{
C obj;
}
程序的輸出是:
A()
B()
~B()
~A()
再看:
struct A
{
A():id(count++)
{
printf("A(%d)\n", id);
}
~A()
{
printf("~A(%d)\n", id);
}
int id;
static int count;
};
//原文是沒有這句的,不過根據C++規范,static數據成員必須在類定義體外定義。
//謝謝yuxq100指出。
int A::count = 0;
int main()
{
A array[4];
}
程序輸出:
A(0)
A(1)
A(2)
A(3)
~A(3)
~A(2)
~A(1)
~A(0)
仔細看著張圖,也會有所收獲:
接下來看看:the rule of three:
If a class defines a copy constructor, acopy assignment operator, or a destructor, then it should define all three.
如果一個類定義了拷貝構造函數、賦值操作符、析構函數中的一個,那麼通常需要全部定義這仨函數。
如圖示:
接下類看看虛函數表:
看一下這段代碼,虛函數表的結構大概如何呢?
struct base
{
virtual void f();
virtual void g();
int a,b;
};
struct derived:base
{
virtual void g();
virtual void h();
int c;
};
void poly(base* ptr)
{
ptr->f();
ptr->g();
}
int main()
{
poly(&base());
poly(&derived());
}
虛函數表結構如何呢?看圖:
簡單說明:派生類沒有重載f函數,它繼承了基類的f函數,因此,派生類的虛函數表的f函數指向基類的f函數。但是,因為派生類重載了g函數,因此,其虛函數表中的g指向自身的g函數。
那麼這段代碼呢?
struct base
{
void f();
virtual void g();
int a,b;
};
struct derived:base
{
virtual void g();
virtual void h();
int c;
};
void poly(base* ptr)
{
ptr->f();
ptr->g();
}
int main()
{
poly(&base());
poly(&derived());
}
基類的f函數不是虛函數了,這個時候的虛函數表結構又如何呢?
越多的同事對他們所使用的語言有深入的認識,這對你有什麼好處嗎?我們不建議(也不實際)要求公司裡所有的C/C++程序員都深入理解C/C++。但是你確實需要絕大部分的程序員真的在意他們的專業度,他們需要求知若渴,不斷努力,爭取不斷的加深對語言本身的理解。正所謂:stay hungry,stay foolish:)
現在回過頭了看著這兩名開發者,也就是我們之前所一直說的候選者。
親,你覺得這兩名開發者之間最大的差別在哪?
關於語言的現有知識嗎? 不是!!
是他們對於學習的態度!!
你最後一次上編程方面的課程是什麼時候?
第一個候選者這樣回答:你什麼意思?我在大學裡學習編程,現在我通過實踐來學習。你想知道什麼?
你:那麼,你現在在閱讀哪些書?
候選者:書?哦,我不需要書。在我需要的時候,我會在網上查詢手冊。
你:你會跟你的同事談論編程方面的東西嗎?
候選者:我覺得沒有必要!!我比他們強多了,從他們身上學不到任何玩意!!
你貌似對C/C++了解的更多,怎麼做到的?
第二個候選者:我每天都會學習一些新東西,我真的樂在其中:)
我偶爾也會在stackoverflow.com、comp.lang.c還有comp.lang.c++跟進一些討論。
我還參加了一個當地的C/C++用戶組,我們定期會舉行一些討論會,交流心得。
我看了很多的書,很多很多。你知道嗎?James Grenning剛剛寫了一本很不錯的書:《Test-Driven Development in C》,很值得一看:)
[PS:貌似是:Test-DrivenDevelopment for Embedded C]
我偶爾會被允許拜訪WG14W以及G21。
[PS:
ISO WG14:ISO C委員會,具體指JTC1/SC22/WG14 C語言技術工作小組,通常簡寫為WG14。 ISO WG21:ISO C++委員會,具體指JTC1/SC22/WG21 C++技術工作小組,通常簡寫成WG21。
此人很牛逼呀:)]
我還是ACCU的會員,這裡的人對於編程都有專業精神。我訂閱了Overload,CVu及accu的一些綜述文章。
[PS:移步看看ACCU的網站,確實應該去看看:
ACCU is an organisation of programmers whocare about professionalism in programming and are dedicated to raising thestandard of programming.
]
候選者接著說:無論何時只要有有機會,我都會參加C/C++課程,倒不是因為跟老師能學到什麼東西,而是因為通過和其他同學的討論,能擴展我的知識面。
但也許最好的知識來源於密切地配合我的同事們工作,與他們交流,分享自己所知的同時,從他們身上學到更多的知識。
(我表示從第二個候選者那學到了很多東西:)
最後,概述:
l 編譯器和鏈接器(連接程序)
l 聲明和定義
l 活動幀
l 內存段
l 內存對齊
l 序點
l 求值順序
l 未定義和未指定
l 優化
l 關於C++的一些玩意
l 對象的恰當初始化
l 對象的生命周期
l 虛函數表
l 以及一些關於專業精神和學習態度的話題
這個時候第一個候選者貌似有所領悟:
第一個候選者:啊?
你:有什麼問題嗎?
候選者:我真的熱愛編程,但是我現在認識到我真的還遠遠說不上專業。對於如何更好的學習C/C++,您能給我一些建議嗎?
你:首先,你必須認識到編程是一件持續學習的的過程。不管你掌握了多少,總有很多知識需要你去學習。其次,你還必須認識到,專業編程最重要的一點是,你必須和你的同事親密合作。想想體育比賽中,沒有人可以做到單憑個人就能贏得比賽。
候選者:好的,我需要好好反省。。。
你:但是話說回來,養成這麼個習慣,偶爾去關注一下代碼所生成的匯編語句。你會發現很多有意思的東西。使用debugger,一步步的跟蹤你的代碼,看看內存的使用情況,同時看看處理器到底在執行什麼指令。
候選者:有什麼關於C/C++的書、網站、課程或是會議值得推薦嗎?
你:要學習更多的現代軟件的開發方式,我推薦James Grenning寫的Test-Driven Development for Embedded C(貌似還沒有中文版)。想要更深入的學習C語言,可以參考Peter van/Der Linden的Expert C Programming(C專家編程),這本書雖然成作已經20多年了,但是書上的觀點依然管用。對於C++,我推薦你從Scott Meyers的Effective C++(國內侯捷老師翻譯了此書)以及Herb Sutter 和Andrei Alexandrescu的C++ coding standards(C++編程規范)。
此外,如果你有機會參加任何於此有關的課程,不要猶豫,參加!只要態度正確,你就可以從老師和其他學生那裡學到很多東西。
最後,我建議加入一些C/C++的用戶組織,投身於社區當中。具體來說,我非常推薦ACCU,他們很專注於C/C++編程。你知道嗎?他們每年的春季都會在牛津大學舉行為期一周的與此相關的會議,與會者是來自全世界專業程序員:)或許明年4月份我會在那遇見你?
候選者:謝謝:)
你:祝你好運:)
全文完。
摘自 Rockics的專欄