程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 【Deep C (and C++)】深入理解C/C++(4)

【Deep C (and C++)】深入理解C/C++(4)

編輯:C++入門知識

譯自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的專欄

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved