李良福
[摘要]C++語(yǔ)言是一門(mén)面向?qū)ο蟮母呒?jí)語(yǔ)言,與C語(yǔ)言相比出現(xiàn)了很多新的概念,正確理解與應(yīng)用這些新的概念是學(xué)好C++語(yǔ)言的關(guān)鍵。本文對(duì)引用與指針的概念以及使用方法的區(qū)別進(jìn)行了詳細(xì)的描述,還對(duì)普通指針、指向常量的指針和常指針三種指針?biāo)赶虻膬?nèi)容和指針本身能否改變進(jìn)行了對(duì)比,對(duì)基類中具有不同訪問(wèn)屬性的成員經(jīng)過(guò)不同方式繼承之后在派生類中的訪問(wèn)權(quán)限也進(jìn)行了比較,對(duì)不同重載方式下運(yùn)算符重載函數(shù)參數(shù)的個(gè)數(shù)也進(jìn)行了總結(jié)。通過(guò)對(duì)這些概念的理解和應(yīng)用,可以提高大學(xué)生初學(xué)者和程序員的學(xué)習(xí)與編程能力。本文作者的教學(xué)實(shí)踐表明,本文的關(guān)鍵概念教學(xué)實(shí)踐起到了良好的教學(xué)效果。
[關(guān)鍵字]面向?qū)ο?C++語(yǔ)言 關(guān)鍵概念 教學(xué)探索
[中圖分類號(hào)]G434 [文獻(xiàn)標(biāo)識(shí)碼]A
一、引言
C++語(yǔ)言是在C語(yǔ)言基礎(chǔ)上發(fā)展的一門(mén)面向?qū)ο蟮母呒?jí)程序設(shè)計(jì)語(yǔ)言,全面兼容C語(yǔ)言[1]。C++語(yǔ)言采用面向?qū)ο蟮乃枷耄瑢⒖陀^事物看作是具有屬性和行為的對(duì)象,能夠更為直接地描述客觀世界中存在的對(duì)象以及它們之間的關(guān)系[2~3]。目前C++語(yǔ)言是大多數(shù)電子、信息、計(jì)算機(jī)等相關(guān)專業(yè)中非常重要的程序設(shè)計(jì)課程,也是這些大學(xué)生在學(xué)習(xí)后續(xù)專業(yè)課、進(jìn)行畢業(yè)設(shè)計(jì)、以后上研究生或參加工作從事計(jì)算機(jī)軟件開(kāi)發(fā)的主要編程語(yǔ)言。本人在多年的教學(xué)探索與實(shí)踐過(guò)程中發(fā)現(xiàn),大學(xué)生對(duì)很多新概念的理解方面存在概念模糊、混淆不清的情況,這主要是C++語(yǔ)言有很多新的概念難以理解,僅憑大學(xué)生在初次學(xué)習(xí)時(shí)很難對(duì)這些概念實(shí)現(xiàn)準(zhǔn)確理解和掌握,需要教師在授課前提前將這些概念進(jìn)行備課總結(jié),在上課時(shí)采用表格形式在多媒體課件中播放,這樣能夠極大提高學(xué)生對(duì)這些概念的領(lǐng)悟和理解能力[4]。本人根據(jù)多年的教學(xué)工作實(shí)踐,總結(jié)出了多個(gè)大學(xué)生在學(xué)習(xí)時(shí)難以區(qū)分和理解的概念,例如引用與指針的概念的區(qū)別,普通指針、指向常量的指針和常指針三種指針的對(duì)比,以及公有、私有、保護(hù)三種繼承方式的區(qū)別都進(jìn)行了詳細(xì)的比較,對(duì)不同重載方式下運(yùn)算符重載函數(shù)參數(shù)的個(gè)數(shù)也進(jìn)行了總結(jié),為大學(xué)生的學(xué)習(xí)和教師的教學(xué)提供了有效參考。
二、引用與指針概念的區(qū)別
引用是面向?qū)ο蟮腃++語(yǔ)言與C語(yǔ)言不同的一個(gè)重要概念,主要用于參數(shù)傳遞,引用的符號(hào)&與C語(yǔ)言的指針取地址運(yùn)算符&、進(jìn)行與操作的位運(yùn)算符&相同,需要進(jìn)行區(qū)分。當(dāng)&符號(hào)出現(xiàn)在程序中,判斷它究竟是引用、位運(yùn)算符還是取地址運(yùn)算符,可以首先看它是否為雙目運(yùn)算符,如果是雙目運(yùn)算符,則為位運(yùn)算符,例如:
則上述程序中&為位運(yùn)算符。
取地址運(yùn)算符&和引用運(yùn)算符&都是單目運(yùn)算符。取地址運(yùn)算符是位于一個(gè)已經(jīng)存在的變量的前面。
則上述程序中就是把整型變量a的地址賦給指針變量p。
引用是標(biāo)識(shí)符的別名。引用是C++中的概念,初學(xué)者容易把引用和指針混淆一起。例如,下面程序中,b是a的一個(gè)引用,a 是被引用物。
程序中的b相當(dāng)于a的別名(或稱綽號(hào)),對(duì)b的任何操作就是對(duì)a的操作。所以b既不是a的拷貝,也不是指向a的指針,其實(shí)b就是a自己。
在下面的示例程序中,c被初始化為a的引用。語(yǔ)句c =b并不能將c修改成為b的引用,只是把c的值改變成為10。由于c 是a的引用,所以a的值也變成了10。
上面的程序看起來(lái)有點(diǎn)像在玩文字游戲,沒(méi)有體現(xiàn)出引用的真正價(jià)值。其實(shí),引用的主要目的和功能是傳遞函數(shù)的返回值和參數(shù)。在C語(yǔ)言中,函數(shù)的返回值和參數(shù)的傳遞方式只有兩種:值傳遞、指針傳遞;而在C++語(yǔ)言中,函數(shù)的返回值和參數(shù)的傳遞方式有三種:值傳遞、指針傳遞和引用傳遞。
下面兩個(gè)例子分別描述了指針和引用參數(shù)傳遞的用法:
1.采用指針進(jìn)行參數(shù)傳遞的例子
2.采用引用進(jìn)行參數(shù)傳遞的例子
1.從現(xiàn)象上看,指針在運(yùn)行過(guò)程中可以改變它所指向的值,而引用一旦和某個(gè)對(duì)象綁定之后就不會(huì)再進(jìn)行改變;
2.從內(nèi)存分配上看,程序會(huì)為指針變量分配一定的內(nèi)存區(qū)域,而引用是和一個(gè)已經(jīng)存在的對(duì)象綁定,不會(huì)再分配內(nèi)存區(qū)域;
3.從編譯上看,指針可以改變所指向的對(duì)象(指針變量中的值可以改變),而引用一旦綁定一個(gè)對(duì)象后就不會(huì)再進(jìn)行改變。
實(shí)際上“引用”可以做的任何事情“指針”也都可以實(shí)現(xiàn),那為什么還要用“引用”這個(gè)概念?這是由于指針能夠毫無(wú)約束地操作內(nèi)存中的任何地址,盡管指針功能十分強(qiáng)大,但是非常危險(xiǎn),很容易把一些重要數(shù)據(jù)破壞。而引用在使用時(shí)只是和一個(gè)已經(jīng)存在的合法的存儲(chǔ)單元關(guān)聯(lián),不會(huì)產(chǎn)生一個(gè)空的引用。
三、指向常量的指針與常指針的區(qū)別
很多大學(xué)生在學(xué)習(xí)普通指針、指向常量的指針和常指針概念時(shí)混淆不清。由于指針功能十分強(qiáng)大,對(duì)上述各種指針概念不清楚,就很容易出現(xiàn)內(nèi)存操作隱患。如果我們希望指針?biāo)赶虻膬?nèi)容不被隨意改變,可以聲明指向常量的指針,此時(shí)不能通過(guò)指針來(lái)改變所指對(duì)象的值,但指針本身可以改變,可以指向另外的對(duì)象。如果我們希望指針本身不被改變,則可以聲明常指針,即指針類型的常量(聲明為地址類型的常量,指針本身就是常量),則指針本身的值不能被隨便改變。表2給出了普通指針、指向常量的指針和常指針在使用時(shí)指針本身和指針?biāo)赶虻膬?nèi)容能否被改變的總結(jié)。
下面給出了四個(gè)例子,分別表示指向常量的指針和常指針?biāo)赶虻膬?nèi)容以及指針本身能否被改變的情況。
1.指向常量的指針的例子,所指向的內(nèi)容不能改變
2.指向常量的指針的例子,指針本身的值可以改變
3.常指針的例子,指針本身不可改變
4.常指針的例子,常指針?biāo)赶虻膬?nèi)容能改變
四、私有、公有與保護(hù)成員的區(qū)別
很多學(xué)生在學(xué)習(xí)私有、公有與保護(hù)成員三個(gè)概念時(shí)混淆不清,在使用從基類中繼承而來(lái)的成員時(shí)不清楚在派生類中是什么訪問(wèn)權(quán)限,從而導(dǎo)致程序編譯或運(yùn)行錯(cuò)誤?;惖某蓡T可以有public(公有類型)、protected(保護(hù)類型)、private(私有類型)三種訪問(wèn)屬性。其實(shí),結(jié)合自然語(yǔ)言中的繼承概念,學(xué)生就很容易理解。公有類型外界能夠看得見(jiàn),能夠被繼承下去。保護(hù)類型外界看不見(jiàn),但是也能夠被繼承下去。私有類型外界看不見(jiàn),能夠被繼承下去,占用內(nèi)存空間,但是在派生類中不可直接訪問(wèn)。保護(hù)類型的成員能夠被繼承下去,在派生類中可以直接訪問(wèn),但是外界看不見(jiàn)。類的繼承方式有public(公有繼承)、protected(保護(hù)繼承)、private(私有繼承)三種。不同的繼承方式,會(huì)導(dǎo)致原來(lái)具有不同訪問(wèn)屬性的基類成員在派生類當(dāng)中具有不同的訪問(wèn)屬性。表3給出了基類不同訪問(wèn)屬性的成員經(jīng)過(guò)不同繼承方式后在派生類中的訪問(wèn)權(quán)限。
從表3可以看出,基類的私有成員無(wú)論經(jīng)過(guò)何種繼承方式都不能在派生類當(dāng)中直接訪問(wèn),但是在派生類中占有內(nèi)存空間。在派生類外部,通過(guò)派生類的對(duì)象只能夠訪問(wèn)到以公有方式從基類繼承過(guò)來(lái)的公有成員。
從表3中還可以看出,保護(hù)類型成員的訪問(wèn)權(quán)限介于公有和私有之間。從橫向(外部訪問(wèn))看,保護(hù)類型的成員和私有類型的成員一樣,在外部通過(guò)派生類的對(duì)象不可直接訪問(wèn)保護(hù)類型的成員。從縱向(繼承與派生關(guān)系)看,保護(hù)類型的成員和公有類型的成員一樣,能夠繼續(xù)派生到下一級(jí)的派生類中去。因此,保護(hù)類型的成員既實(shí)現(xiàn)了數(shù)據(jù)共享(縱向看),又實(shí)現(xiàn)了數(shù)據(jù)隱藏(橫向看),在數(shù)據(jù)的共享與保護(hù)之間找到了一個(gè)平衡點(diǎn),有利于代碼的復(fù)用與擴(kuò)充。
五、運(yùn)算符重載函數(shù)參數(shù)個(gè)數(shù)的確定
普通的運(yùn)算符只能對(duì)基本類型的變量進(jìn)行運(yùn)算。C++提供了運(yùn)算符重載的功能,能夠?yàn)橐粋€(gè)已有的運(yùn)算符提供多重含義。重載后的運(yùn)算符能夠?qū)ψ远x數(shù)據(jù)類型的變量進(jìn)行運(yùn)算。在C++語(yǔ)言中,運(yùn)算符重載有兩種形式,分別是重載為類的成員函數(shù)和類的非成員函數(shù)。
重載為類的成員函數(shù)時(shí),參數(shù)個(gè)數(shù)等于原來(lái)操作數(shù)的個(gè)數(shù)減去1(后置++、后置--運(yùn)算符除外)。如果某一個(gè)對(duì)象使用重載了的成員函數(shù),對(duì)象自身的數(shù)據(jù)可以直接訪問(wèn),因此就不再需要放在參數(shù)表中進(jìn)行傳遞,少了的操作數(shù)就是該對(duì)象本身。
當(dāng)重載為非成員函數(shù)(通常為友元函數(shù))時(shí),由于友元函數(shù)不屬于任何一個(gè)類,利用友元函數(shù)對(duì)某一個(gè)對(duì)象的數(shù)據(jù)成員進(jìn)行操作時(shí),就必須利用該對(duì)象的名稱來(lái)進(jìn)行,因此所有使用到的參數(shù)都必須進(jìn)行傳遞,參數(shù)個(gè)數(shù)等于原來(lái)操作數(shù)的個(gè)數(shù)(后置++、后置--運(yùn)算符除外),而且至少應(yīng)該有一個(gè)參數(shù)為自定義類型的形參。
在C++語(yǔ)言中,為了區(qū)別前置和后置的單目運(yùn)算符自增自減運(yùn)算,后置自增與自減單目運(yùn)算符要在形參列表中增加一個(gè)int類型的參數(shù)來(lái)區(qū)分。綜上所述,我們采用表4來(lái)總結(jié)一下不同重載方式下運(yùn)算符重載函數(shù)參數(shù)個(gè)數(shù)的確定方法。
從表4中可以看出,雙目運(yùn)算符重載為類的成員函數(shù)時(shí)參數(shù)為1個(gè),重載為友元函數(shù)時(shí)參數(shù)為2個(gè)。前置自增、自減運(yùn)算符重載為類的成員函數(shù)時(shí)參數(shù)為0個(gè),重載為友元函數(shù)時(shí)參數(shù)為1個(gè);后置自增、自減運(yùn)算符重載為類的成員函數(shù)時(shí)參數(shù)為1個(gè),重載為友元函數(shù)時(shí)參數(shù)為2個(gè)。
六、結(jié)論
本文對(duì)面向?qū)ο蟮腃++語(yǔ)言中幾個(gè)難以理解的概念進(jìn)行了詳細(xì)描述與分析,使得大學(xué)生在學(xué)習(xí)C++語(yǔ)言中一些新的概念時(shí)能夠得到很好的理解與應(yīng)用。本文中引用與指針概念的區(qū)別,各種指針使用方法的比較、各種繼承方式、運(yùn)算符重載函數(shù)參數(shù)的個(gè)數(shù)的總結(jié)都采用表格的形式進(jìn)行了對(duì)比,清晰明了,能夠提高大學(xué)生對(duì)面向?qū)ο蟮年P(guān)鍵概念的理解和掌握能力。
基金項(xiàng)目:本文研究得到了國(guó)家自然科學(xué)基金資助(項(xiàng)目編號(hào):61201434)、中國(guó)博士后基金特別資助(項(xiàng)目編號(hào):200902593)、教育部博士點(diǎn)基金資助(項(xiàng)目編號(hào):20090202120002)。
[參考文獻(xiàn)]
[1]鄭莉.C++語(yǔ)言程序設(shè)計(jì)[M].北京:清華大學(xué)出版社,2010.
[2]錢(qián)能.C++程序設(shè)計(jì)教程[M].北京:清華大學(xué)出版社,2009.
[3]譚浩強(qiáng).C++面向?qū)ο蟪绦蛟O(shè)計(jì)[M].北京:清華大學(xué)出版社,2006.
[4]范虹.論免費(fèi)師范生信息技術(shù)能力的培養(yǎng)[J],中國(guó)電化教育,2011(5): 31-34.
(作者單位:陜西師范大學(xué) 計(jì)算機(jī)科學(xué)學(xué)院 陜西西安)