杜青
摘要:“C++面向?qū)ο蟪绦蛟O(shè)計(jì)”課程涉及了很多的知識(shí)點(diǎn),學(xué)生很難在短時(shí)間內(nèi)掌握面向?qū)ο蟪绦蛟O(shè)計(jì)的核心思想。為此介紹了在該門課程教學(xué)中采用的教學(xué)方法,對(duì)課程中重要的知識(shí)點(diǎn)如類的概念、類的繼承機(jī)制等內(nèi)容,通過例題詳細(xì)闡述;對(duì)于難點(diǎn)問題,如構(gòu)造函數(shù)、運(yùn)算符重載等,通過例題分步驟進(jìn)行講解,由淺入深,使學(xué)生盡快理解和掌握。這種教學(xué)方式在該門課程的教學(xué)中加以應(yīng)用,取得了較好的效果。
關(guān)鍵詞:C++;面向?qū)ο?;程序設(shè)計(jì);類;教學(xué)方法
中圖分類號(hào): TP311 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2015)34-0118-03
Abstract: There are lots of knowledge points included in the course, C++ Object-Oriented programming, which makes it hard for students to grasp the key ideas of it. This paper introduces the teaching methods in the course to elaborates the key points like classes and their inheritance mechanism, and explains the difficult points like constructors, operators, etc step by step by focusing on examples, which facilitates the comprehension of students. This teaching method has been successfully applied in the course, and a good result has been obtained.
Key words: C++; object-oriented; programming; classes; teaching methods
1 概述
“C++面向?qū)ο蟪绦蛟O(shè)計(jì)”是計(jì)算機(jī)專業(yè)學(xué)生一門重要的專業(yè)基礎(chǔ)課,學(xué)生在掌握C++結(jié)構(gòu)化程序設(shè)計(jì)的基礎(chǔ)上,通過這門課程的學(xué)習(xí),進(jìn)一步掌握C++面向?qū)ο蟪绦蛟O(shè)計(jì)的基礎(chǔ)知識(shí)。
由于“C++面向?qū)ο蟪绦蛟O(shè)計(jì)”涉及的知識(shí)點(diǎn)非常多,初學(xué)者很難在短時(shí)間內(nèi)領(lǐng)會(huì)面向?qū)ο蟪绦蛟O(shè)計(jì)的核心思想,在面對(duì)實(shí)際問題時(shí),難以用面向?qū)ο蟪绦蛟O(shè)計(jì)的方法構(gòu)建出合理的程序框架。
因此在“C++面向?qū)ο蟪绦蛟O(shè)計(jì)”課程的教學(xué)中,需要抓住重點(diǎn),理清難點(diǎn)。對(duì)類的概念、繼承的機(jī)制等關(guān)鍵知識(shí)點(diǎn)著重闡述,使學(xué)生掌握面向?qū)ο蟪绦虻幕窘Y(jié)構(gòu);針對(duì)難點(diǎn)問題,如構(gòu)造函數(shù)與運(yùn)算符重載等,結(jié)合具體實(shí)例,由淺入深進(jìn)行分析,使學(xué)生掌握面向?qū)ο蟪绦蛟O(shè)計(jì)的基本方法。
2 建立類的概念
類的概念是面向?qū)ο蟪绦蛟O(shè)計(jì)的基礎(chǔ),體現(xiàn)了面向?qū)ο蟪绦蛟O(shè)計(jì)的兩大特性,即抽象性與封裝性。
在進(jìn)行結(jié)構(gòu)化程序設(shè)計(jì)時(shí),根據(jù)題目要求,先設(shè)計(jì)函數(shù),再在主函數(shù)中定義變量,存放原始數(shù)據(jù),之后調(diào)用函數(shù)進(jìn)行處理操作,最后輸出結(jié)果。
在進(jìn)行面向?qū)ο蟪绦蛟O(shè)計(jì)時(shí),要先根據(jù)題目要求設(shè)計(jì)類,再在主函數(shù)中定義類對(duì)象,存放待處理數(shù)據(jù),接著調(diào)用類的成員函數(shù)實(shí)現(xiàn)處理操作并輸出結(jié)果。
因此類的設(shè)計(jì)是進(jìn)行面向?qū)ο蟪绦蛟O(shè)計(jì)的關(guān)鍵步驟。在介紹類的設(shè)計(jì)時(shí),先從一個(gè)簡(jiǎn)單的類——學(xué)生類入手,使學(xué)生對(duì)類的概念有一個(gè)初步的了解。在此基礎(chǔ)上,再將一些C++結(jié)構(gòu)化程序設(shè)計(jì)的經(jīng)典例題,如求給定范圍素?cái)?shù)、一維數(shù)組應(yīng)用、二維數(shù)組應(yīng)用等,改用面向?qū)ο蟪绦蛟O(shè)計(jì)的方法去實(shí)現(xiàn),使學(xué)生進(jìn)一步了解類的設(shè)計(jì)過程,能夠根據(jù)題目要求,確定類中的數(shù)據(jù)成員及成員函數(shù),從而掌握類設(shè)計(jì)的基本方法。
在完成類設(shè)計(jì)的基礎(chǔ)上,進(jìn)一步掌握類的應(yīng)用,即定義類對(duì)象和調(diào)用類的成員函數(shù),從而掌握面對(duì)象程序設(shè)計(jì)的基本步驟。
3 理解類的繼承機(jī)制
類的繼承性是面向?qū)ο蟪绦蛟O(shè)計(jì)的重要特性。通過類的繼承機(jī)制,實(shí)現(xiàn)了軟件代碼的重用。
在講述單繼承時(shí),先通過簡(jiǎn)單的例題,例如學(xué)生類,介紹單繼承的概念,繼承的方式,派生類從基類繼承成員的訪問屬性,以及在派生類中如何新增成員和改寫基類已有的成員,派生類構(gòu)造函數(shù)及析構(gòu)函數(shù)的執(zhí)行過程。
再通過較復(fù)雜的例題,例如圖形類,進(jìn)一步介紹如何根據(jù)題目要求,設(shè)計(jì)基類及派生類,如何確定基類及派生類的數(shù)據(jù)成員及成員函數(shù),如何定義基類及派生類的構(gòu)造函數(shù)等。
在講述多重繼承時(shí),通過簡(jiǎn)單的例題,例如家具類,介紹多重繼承的概念,繼承的方式,派生類構(gòu)造函數(shù)及析構(gòu)函數(shù)的執(zhí)行過程,多重繼承的二義性問題以及二義性問題的解決方法——虛擬繼承等。
由于給出具體實(shí)例,使學(xué)生對(duì)復(fù)雜的繼承機(jī)制有了直觀的了解,在解決實(shí)際問題時(shí),能夠根據(jù)要求,建立基類,并由基類派生子類,實(shí)現(xiàn)軟件代碼的復(fù)用。
4 難點(diǎn)問題的分析
C++面向?qū)ο蟪绦蛟O(shè)計(jì)的基礎(chǔ)知識(shí)中有一些概念比較復(fù)雜,難以理解??梢酝ㄟ^一些簡(jiǎn)單的例題,分步驟說明概念的含義,提高學(xué)生對(duì)復(fù)雜概念的理解能力。
4.1 類對(duì)象的初始化
定義類對(duì)象時(shí),會(huì)自動(dòng)調(diào)用類的構(gòu)造函數(shù)實(shí)現(xiàn)類對(duì)象的初始化。構(gòu)造函數(shù)的概念中,復(fù)制構(gòu)造函數(shù)、類繼承中構(gòu)造函數(shù)的執(zhí)行過程,是構(gòu)造函數(shù)概念的難點(diǎn)。
4.1.1復(fù)制構(gòu)造函數(shù)
復(fù)制構(gòu)造函數(shù)可以將一個(gè)已有對(duì)象的值賦給一個(gè)新對(duì)象。如不定義復(fù)制構(gòu)造函數(shù),系統(tǒng)提供默認(rèn)的復(fù)制構(gòu)造函數(shù),而默認(rèn)復(fù)制構(gòu)造函數(shù)只能實(shí)現(xiàn)淺復(fù)制,如要實(shí)現(xiàn)深復(fù)制,就需要自定義復(fù)制構(gòu)造函數(shù)。
在講述復(fù)制構(gòu)造函數(shù)時(shí),先通過學(xué)生類例題,分析復(fù)制構(gòu)造函數(shù)的特點(diǎn),以及調(diào)用復(fù)制構(gòu)造函數(shù)的各種情況,再修改類中的普通構(gòu)造函數(shù),在該函數(shù)中申請(qǐng)一定的內(nèi)存資源。通過查看運(yùn)行結(jié)果中的錯(cuò)誤,分析出現(xiàn)錯(cuò)誤的原因及解決的辦法,之后修改已有的復(fù)制構(gòu)造函數(shù),增加代碼,實(shí)現(xiàn)深復(fù)制,最終程序能夠正常運(yùn)行。通過一系列的分析,學(xué)生知道了在什么情況下需要實(shí)現(xiàn)深復(fù)制,以及實(shí)現(xiàn)深復(fù)制的方法,加深了對(duì)概念的理解和記憶。
學(xué)生類例題的主要代碼如下。
class Student
{public:
Student(long nu=0,char na[]="noname"):num(nu)
{ name=new char[20]; strcpy(name,na); }
Student(const Student& s):num(s.num) //復(fù)制構(gòu)造函數(shù)定義
{ name=new char[20]; strcpy(name,s.name);} //實(shí)現(xiàn)深復(fù)制
void show()
{ cout long num; char *name; }; void func(Student st3) //按值傳遞參數(shù)時(shí)調(diào)用復(fù)制構(gòu)造函數(shù) { st3.show();} int main() { Student st1(1001,"Zhang"),st2(st1); //定義對(duì)象時(shí)調(diào)用復(fù)制構(gòu)造函數(shù) st2.show(); func(st2); return 0;} 4.1.2 類繼承時(shí)構(gòu)造函數(shù)的執(zhí)行過程 定義派生類對(duì)象時(shí),自動(dòng)調(diào)用派生類的構(gòu)造函數(shù)。由于存在單繼承、多重繼承、虛擬繼承以及對(duì)象數(shù)據(jù)成員等多種情況,分析類繼承時(shí)構(gòu)造函數(shù)的執(zhí)行過程,需要分以下5種情況,通過例題分別加以討論。 ⑴ 單繼承時(shí)派生類構(gòu)造函數(shù)的執(zhí)行過程 在學(xué)生類例題中,使學(xué)生類派生出大學(xué)生類,再定義大學(xué)生類對(duì)象,通過查看運(yùn)行結(jié)果,使學(xué)生看到基類構(gòu)造函數(shù)及派生類構(gòu)造函數(shù)的執(zhí)行順序,進(jìn)而介紹當(dāng)基類構(gòu)造函數(shù)帶有參數(shù)時(shí),派生類構(gòu)造函數(shù)如何向它傳遞實(shí)際參數(shù)。 ⑵ 單繼承時(shí)派生類中有對(duì)象數(shù)據(jù)成員時(shí)構(gòu)造函數(shù)的執(zhí)行過程 在大學(xué)生類中,增加對(duì)象數(shù)據(jù)成員,即教師類對(duì)象,通過該例題,使學(xué)生看到定義派生類對(duì)象時(shí),基類構(gòu)造函數(shù)、對(duì)象成員構(gòu)造函數(shù)、派生類構(gòu)造函數(shù)的執(zhí)行順序,進(jìn)而介紹派生類構(gòu)造函數(shù)如何向?qū)ο髷?shù)據(jù)成員的構(gòu)造函數(shù)傳遞實(shí)際參數(shù)。 ⑶ 多重繼承時(shí)派生類構(gòu)造函數(shù)的執(zhí)行過程 通過家具類例題,使學(xué)生看到定義派生類對(duì)象時(shí),多個(gè)基類構(gòu)造函數(shù)以及派生類構(gòu)造函數(shù)的執(zhí)行順序。 ⑷ 虛擬繼承時(shí)派生類構(gòu)造函數(shù)的執(zhí)行過程 通過家具類例題,使學(xué)生看到定義派生類對(duì)象時(shí),虛基類及直接基類構(gòu)造函數(shù)、派生類構(gòu)造函數(shù)的執(zhí)行順序,進(jìn)而介紹派生類構(gòu)造函數(shù)如何向虛基類構(gòu)造函數(shù)傳遞實(shí)際參數(shù)。 ⑸ 多重繼承時(shí)既有虛擬繼承也有非虛擬繼承時(shí)派生類構(gòu)造函數(shù)的執(zhí)行過程 通過例題,使學(xué)生看到定義派生類對(duì)象時(shí),虛基類、非虛基類構(gòu)造函數(shù)以及派生類構(gòu)造函數(shù)的執(zhí)行順序。 通過以上分步驟講解,使學(xué)生對(duì)比較復(fù)雜的構(gòu)造函數(shù)的執(zhí)行過程有直觀、清晰的認(rèn)識(shí)。 4.2 類對(duì)象的運(yùn)算 運(yùn)算符重載是面向?qū)ο蟪绦蛟O(shè)計(jì)中比較重要的概念。通過重載運(yùn)算符,可以使C++已有的運(yùn)算符能夠用于類對(duì)象的運(yùn)算。 重載雙目運(yùn)算符時(shí),由于存在對(duì)象與對(duì)象的運(yùn)算、對(duì)象與基本類型數(shù)據(jù)的運(yùn)算,以及基本類型數(shù)據(jù)與對(duì)象的運(yùn)算3種情況,若要定義3個(gè)運(yùn)算符重載函數(shù)實(shí)現(xiàn)這3種運(yùn)算,則比較繁瑣。對(duì)后2種情況,可以通過定義轉(zhuǎn)換構(gòu)造函數(shù)或重載類型轉(zhuǎn)換運(yùn)算符,將兩種不同類型的操作數(shù)轉(zhuǎn)換為同一類型數(shù)據(jù)再進(jìn)行運(yùn)算。 ⑴ 將基本類型數(shù)據(jù)轉(zhuǎn)換為對(duì)象 利用轉(zhuǎn)換構(gòu)造函數(shù),可以將基本類型數(shù)據(jù)轉(zhuǎn)換為類對(duì)象。介紹轉(zhuǎn)換構(gòu)造函數(shù)時(shí),通過復(fù)數(shù)類例題,講清楚在類中定義轉(zhuǎn)換構(gòu)造函數(shù)的方法,以及轉(zhuǎn)換構(gòu)造函數(shù)與運(yùn)算符重載函數(shù)配合使用,實(shí)現(xiàn)基本類型數(shù)據(jù)與類對(duì)象運(yùn)算的過程。主要代碼如下。 class Complex {public: Complex(double r=0,double i=0):real(r),imag(i) { } Complex(double r):real(r),imag(0){} //轉(zhuǎn)換構(gòu)造函數(shù) void show() { cout< { } Complex(double r):real(r),imag(0){} operator double() //重載類型轉(zhuǎn)換運(yùn)算符 { return real; } void show() { cout double real,imag; }; int main() { Complex c1(3,5),c2(4.1,10); double d=10+c2; cout<