




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第7章類與對象(一)面向對象的基本概念類的定義創建對象構造函數與析構函數對象數組this指針靜態成員友元類的作用域12/19/20221類和對象第7章類與對象(一)面向對象的基本概念12/16/2022面向對象的基本概念*1.面向對象與面向過程的區別:我要開車去新疆面向過程我開車,我過陜西,我過蘭州……面向對象我命令車去新疆車怎么去我不關心(封裝)12/19/20222類和對象面向對象的基本概念*1.面向對象與面向過程的區別:12/12.類(class)和對象(object)的概念對象是系統中用來描述客觀事務的一個實體,它通過“屬性attribute(數據成員)”和“行為behavior(成員函數、方法)”來分別實體的靜態屬性和動態屬性。類是具有共同屬性和行為的對象的抽象。對象是類的實例(instance)。學生A抽象類對象學生學號姓名學習()學生A學號=101姓名=TOM實例化12/19/20223類和對象2.類(class)和對象(object)的概念對象是系統中*3.類(對象)之間的關系關聯關系教師姓名教學(學生A)學生學號姓名學習()學校12/19/20224類和對象*3.類(對象)之間的關系關聯關系教師姓名教學(學生A)繼承關系(一般和特殊)xx是一種XX類的繼承層次12/19/20225類和對象繼承關系(一般和特殊)xx是一種XX類的繼承層次12/16/聚合關系(整體和部分)隊長隊員球隊聚集頭身體人組合12/19/20226類和對象聚合關系(整體和部分)隊長隊員球隊聚集頭身體人組合1多態車go()大卡車go()小汽車go()12/19/20227類和對象多態車go()大卡車go()小汽車go()12/16/202面向對象的設計思想有那些類(對象)?每一種類(對象)有哪些屬性和方法?類(對象)之間有哪些關系?12/19/20228類和對象面向對象的設計思想有那些類(對象)?12/16/20228類類的定義類的定義格式一般分為說明部分和實現部分。說明部分:是用來說明類中的成員,包含數據成員的說明和成員函數的說明。成員函數是用來對數據成員進行操作的,也稱為“方法”。實現部分:是用來對成員函數進行定義。12/19/20229類和對象類的定義類的定義格式一般分為說明部分和實現部分。12/16/說明部分的一般格式class類類型名{
public:公有成員說明
private:
私有成員說明};私有訪問權限,為默認值,可缺省公有訪問權限除本類中的成員函數及友元外,其他類外函數不能訪問。程序中的任何函數都可訪問12/19/202210類和對象說明部分的一般格式class類類型名私有訪問權限,為默認值例如:定義一個Person類,設Person具有的特征:屬性(姓名、年齡、性別),方法(輸出一個人的屬性);則對應著有4個成員:三個數據成員,一個成員函數。三個數據成員定義為私有成員,print成員函數定義為公有成員。則有:classCPerson{
public:voidprint();
private:charname[10];intage;charsex;};類名通常用C字母開始,以區別其他標識符12/19/202211類和對象例如:定義一個Person類,設Person具有的特征:屬性類的實現部分類的實現部分即定義它的成員函數,如在類說明內部定義,則方式與定義普通函數大體相同。若在類說明外部定義成員函數,則應使用類域運算符::(p21)指明該函數是哪個類中的成員函數。格式為:函數類型類名::成員函數名(形參表){函數體;}voidCPerson::print(){cout<<name<<age<<sex<<endl;}除特殊指明外,成員函數操作的是同一對象中的數據成員。不同的類允許有相同名稱的成員函數,因此,在類外定義成員函數的實現時,必須在成員函數名前加上所屬類名和作用域操作符“::”。12/19/202212類和對象類的實現部分類的實現部分即定義它的成員函數,如在類說明內部定當成員函數的規模較小時,可在類中定義成員函數,成為內聯成員函數。例:classCDate{
public:voidsetDate(intm,intd,inty)//置日期值{ month=m;day=d;year=y;} voidprint();
private:intmonth,day,year;};voidCDate::print(){cout<<year<<'.'<<month<<'.'<<day<<endl;}若將內聯成員函數定義在類說明之外則要加上inline。內聯成員函數12/19/202213類和對象當成員函數的規模較小時,可在類中定義成員函數,成為內聯成員函注意事項1.在類體中不允許對所定義的數據成員進行初始化。classCDate{public:…private:intyear(1998),month(4);…};2.類中的數據成員的類型可以是任意的,包括整型、浮點型、字符型、數組、指針和引用等,也可以是另一個類的對象。3.習慣將類的定義代碼放到一個頭文件中,以后若要使用則用文件包含命令包含。錯誤testClass\CreateClass.cpp12/19/202214類和對象注意事項1.在類體中不允許對所定義的數據成員進行初始化。錯誤創建對象1.對象的定義形式為:類名
對象名列表;
CDatedate1,date2;//定義兩個CDate類的對象date1和date2
CDate*pDate=&date1;
//定義一個指向date1對象空間的指針pDateCDate&rDate=date2;//定義一個引用對象rDateCDatedata[3];//定義一個data對象數組,其元素類型為CDate類定義了一個類只是定義了一種類型,它并不分配空間,不能進行操作。只有用它創建對象后,系統才為對象分配存儲空間。12/19/202215類和對象創建對象1.對象的定義形式為:定義了一個類只是定義了一種類型成員的訪問通過對象可以訪問類中的公有類型數據和成員函數。其使用方式為:
對象名.成員函數名對象名.數據成員例:date1.year=2002;date1.Print();用指針訪問對象公有成員:指針名->數據成員或指針名->成員函數(*指針名).數據成員或(*指針名).成員函數例:pDate->day=30;pDate->Print();(*pDate).day=30;(*pDate).Print();用引用訪問對象成員:引用名.數據成員或引用名.成員函數例:rDate.year=2008;rDate.Print();12/19/202216類和對象成員的訪問通過對象可以訪問類中的公有類型數據和成員函數。其使注意:在成員函數中訪問成員無須加對象名來作為前綴。如:voidCDate::print(){cout<<year<<'.'<<month<<'.'<<day<<endl;}在year等成員之前不能加對象名,在定義類時,成員函數是所有對象共享的代碼,不被某一個對象獨占。也無法確定類的對象名。注意12/19/202217類和對象注意:注意12/16/202217類和對象例一個完整的程序//CDate.hclassCDate{public:voidsetDate(intm,intd,inty)//置日期值{ month=m;day=d;year=y;} voidprint();private:intmonth,day,year;};voidCDate::print(){cout<<year<<'.'<<month<<'.'<<day<<endl;}12/19/202218類和對象例一個完整的程序//CDate.h12/16/202218續例一個完整的程序#include<iostream.h>#include"CDate.h"voidmain(){CDatedate1;date1.setDate(8,5,1996);date1.print();
//cout<<date1.year<<endl;/*CDate*pDate=&date1;pDate->print();*/}testClass\testCDate.cpp12/19/202219類和對象續例一個完整的程序#include<iostream.類的成員函數內聯函數:指定義在類體內的成員函數。外聯函數:指說明在類體內,定義在類體外的成員函數。類外定義的函數缺省情況下都是外聯函數,用關鍵字inline
可以強制轉換。
對于內聯成員函數,編譯時在所有調用該函數的地方將裝入實際的函數代碼。1.內聯函數和外聯函數12/19/202220類和對象類的成員函數內聯函數:指定義在類體內的成員函數。對于內聯成classCDate{public:voidsetDate(intm,intd,inty)//內聯函數之一{ month=m;day=d;year=y;}voidprint();private:intmonth,day,year;};inlinevoidCDate::print()//內聯函數之二{cout<<year<<'.'<<month<<'.'<<day<<endl;}12/19/202221類和對象classCDate12/16/202221類和對象2.設置參數的缺省值函數在定義時可以預先定義出形參的缺省值。調用時如果給出實參,則用實參初始化形參,如果沒有給出實參,則采用預先定義形參的缺省值。例如:voidsetDate(intm,intd=28,inty=2008);
//缺省參數按從右往左的方式或voidsetDate(intm,intd=28,inty=2008){…}在進行函數調用時,主調函數的實參與被調函數的形參按從左到右的位置結合。TestParaDefault.cpp12/19/202222類和對象2.設置參數的缺省值函數在定義時可以預先定義出形參的缺省值3.函數的重載函數的重載:出現在相同作用域的兩個函數,如果具有相同的名字而形參表不同,則稱為重載函數(overloadedfunction)。調用時,會根據不同的參數表選擇對應的成員函數。重載函數,必須:函數名相同,函數的作用域相同,函數的參數個數或參數類型不同。使用重載函數時應注意:⑴只有返回值不同,不能成為重載函數。
intmax(inta,intb);doublemax(inta,intb); //錯誤⑵使用帶缺省值的函數時,可能引發錯誤。如:
intmax(inta,intb=0);intmax(intc);當用一個實參調用該函數時,如max(2),則會出現調用歧義性12/19/202223類和對象3.函數的重載函數的重載:出現在相同作用域的兩個函數,如果構造函數和析構函數構造函數和析構函數都是類的成員函數,是特殊的成員函數,不能被調用而由系統自動調用/執行。構造函數名與類名相同;析構函數名為類名前加“~”。構造函數的功能是在創建對象時給對象分配內存空間,并可使用給定值來初始化對象。析構函數的功能是用來釋放一個對象的已分配空間。并可在對象被清除前,完成一些清理工作。12/19/202224類和對象構造函數和析構函數構造函數和析構函數都是類的成員函數,是特殊對前面的日期類進行修改,并將定義存放在CDate1.h文件中。如:classCDate1
{public:CDate1(inty,intm,intd);~CDate1();voidprint();private:intyear,month,day;
};函數名與類名一致,無類型但可有參數名字與類名一致,前有~,無類型無參數12/19/202225類和對象對前面的日期類進行修改,并將定義存放在CDate1.h文件中CDate1::CDate1(intm,intd,inty){month=m;day=d;year=y;cout<<"Constructorcalled.\n";}CDate1::~CDate1(){cout<<"Destructorcalled.\n";}voidCDate1::print(){cout<<year<<"."<<month<<"."<<day<<endl;}與其他成員函數定義一樣,兩種函數的定義可放在類體內,也可放在類體外12/19/202226類和對象CDate1::CDate1(intm,intd,int#include<iostream.h>#include"CDate1.h"voidmain(){CDate1today(2007,4,1),tomorrow(2007,4,2);cout<<"todayis";today.print();cout<<"tomorrowis";tomorrow.print();}執行程序后,輸出結果為:函數結束時,自動調用析構ConstructorCalled.ConstructorCalled.todayis2007.4.1tomorrowis2007.4.2Destructorcalled.Destructorcalled.12/19/202227類和對象#include<iostream.h>函數結束時,自動調構造函數的特點有:程序中一般不直接調用構造函數,在創建對象時系統自動調用構造函數。構造函數可以重載,即可定義多個參數個數不同的函數構造函數有隱含的返回值,并由系統內部使用析構函數的特點有:一個類中只能定義一個析構函數,即不能重載析構函數可以被調用,也可系統調用被自動調用的情況有兩種:在一個函數體內定義的一個對象,當函數結束時用new運算符動態創建的一個對象,在使用delete釋放時12/19/202228類和對象構造函數的特點有:12/16/202228類和對象缺省構造函數和缺省析構函數在類定義中可以不定義任何構造函數,這時編譯器會自動生成一個不帶參數的缺省構造函數。其格式為:
<類名>::<缺省構造函數名>(){}則在程序中定義一個對象而未指明初始化時,編譯器便按缺省構造函數來初始化該對象。若定義了構造函數,則編譯器就不會再生成缺省構造函數,必須使用定義的構造函數創建對象。同理,若一個類中未定義析構函數,編譯系統也生成一個缺省析構函數。其格式為:<類名>::~<缺省析構函數名>(){}這也是前面的程序中可以沒有構造和析構函數的原因12/19/202229類和對象缺省構造函數和缺省析構函數在類定義中可以不定義任何構造函數,classCConstruct{ public:CConstruct(intx,inty);CConstruct(); voidprint(); private: intm1,m2;};CConstruct::CConstruct(intx,inty){ m1=x; m2=y;}CConstruct::CConstruct(){ m1=0; m2=0;}TestConsOverLoad.cpp例:12/19/202230類和對象classCConstructTestConsOverLovoidCConstruct::print(){cout<<m1<<","<<m2<<endl;}voidmain(){ CConstructc2; CConstructc1(3,4);c1.print();}不帶參數創建對象,調用無參構造函數12/19/202231類和對象voidCConstruct::print()不帶參數創拷貝初始化構造函數構造函數除可以用基本數據類型初始化對象外,還可以使用已存在的同類型的對象即類類型的對象來初始化正在創建的對象。為此,必須在類中定義一個特殊的構造函數來完成這個工作,這個構造函數被稱為拷貝初始化構造函數。格式為:<類名>::<拷貝初始化構造函數名>(<類名>&<引用名>){…}如:student::student(student&s){…}每個類中必須有一個。若類中未說明,則編譯系統會自動生成缺省函數。12/19/202232類和對象拷貝初始化構造函數構造函數除可以用基本數據類型初始化對象外,classCMyClass{ public: CMyClass(intx); CMyClass(CMyClass&c); private: intmember;};CMyClass::CMyClass(intx){member=x;}CMyClass::CMyClass(CMyClass&c){ cout<<"copyconstructorcalled"<<endl; member=c.member;}拷貝初始化構造函數TestCopyConstructor.cpp12/19/202233類和對象classCMyClass拷貝初始化構造函數TestCo拷貝初始化構造函數被自動調用有三種情況:一、是用一個已知對象初始化一個新對象時。二、是以值調用方式向一個函數傳遞對象參數時。三、當對象作為函數返回值時。CMyClassfun(CMyClassd);voidmain(){ CMyClassb(3);
CMyClassc(b); CMyClasss=fun(c);}CMyClassfun(CMyClassd){ returnd;}12/19/202234類和對象拷貝初始化構造函數被自動調用有三種情況:12/16/2022內存解析member:3bMyClass(intx)MyClass(MyClass&c)cmember:3member:3dmember:3*member:3s12/19/202235類和對象內存解析member:3bMyClass(intx)MyC對象數組對象數組:一個數組中的每個數組元素都為同一類的對象。對象數組的定義有以下幾種形式:類中只有無參的構造函數類名數組名[常量表達式];例:CDate2objArray[4];類中只有需要參數的構造函數類名數組名[常量表達式]={構造函數名(參數表),…,構造函數名(參數表)};例:CDate2objArray[2]={CDate1(2002,3,4),CDate1(2008,5,26)};類中有無參的構造函數和有參的構造函數12/19/202236類和對象對象數組對象數組:一個數組中的每個數組元素都為同一類的對訪問數組元素對象的成員objArray[1].print()或(objArray+1)->print()testObjectArray.cpp12/19/202237類和對象訪問數組元素對象的成員testObjectArray.cpp每一個類的非靜態成員函數中的都有一個指針形參this,用于指向正在操作該成員函數的對象。例如:classCDate3{ public: CDate3(inty,intm,intd); voidprint(CDate3*t); voidprint(); private: intyear,month,day;};CDate3::CDate3(inty,intm,intd){ year=y;month=m; day=d;}this指針testThis.cpp12/19/202238類和對象每一個類的非靜態成員函數中的都有一個指針形參this,用于voidCDate3::print(CDate3*t){cout<<t->year<<"."<<t->month<<"."<<t->day<<endl;}voidCDate3::print(){cout<<this->year<<"."<<this->month<<"."<<this->day<<endl;}#include<iostream.h>#include"CDate3.h"voidmain(){ CDate3objThis(2008,4,23);objThis.print(&objThis);objThis.print();}隱含的指針形參this12/19/202239類和對象voidCDate3::print(CDate3*t)隱靜態成員定義類時,可用關鍵字static聲明的數據成員或成員函數稱為靜態成員,包括靜態數據成員和靜態成員函數。靜態數據成員是在編譯時被創建,與對象是否存在無關,其內存空間為數據區,其生命期一直到程序結束。靜態數據成員必須在類外初始化:
數據類型類名::成員名=初始值;靜態成員函數屬于類,而不是對象成員(無this指針用來存放對象的地址),不能直接引用具體對象中的非靜態成員。須使用(對象名.成員名)來引用。可以通過對象名或類名來訪問靜態成員。12/19/202240類和對象靜態成員定義類時,可用關鍵字static聲明的數據成員或成員靜態數據成員#include<iostream.h>classCCat{ public:
staticintcount; CCat(intcolor) {count++;colorFur=color;} private: intcolorFur;};intCCat::count=0;voidmain(){CCatmm(0);CCatpp(1);cout<<CCat::count<<endl;cout<<mm.count<<endl;}CCat::count++12/19/202241類和對象靜態數據成員#include<iostream.h>CCa靜態成員函數classM{public:M(inta){A=a;}
staticvoidf1(Mm);private:intA;staticintB;};intM::B=0;voidM::f1(Mm){cout<<m.A<<B<<endl;}voidmain(){Mp(5);
M::f1(p);//p.f1(p);}靜態成員聲明靜態成員定義引用非靜態成員引用靜態成員函數testStaticFunction.cpp12/19/202242類和對象靜態成員函數classM{靜態成員聲明靜態成員定義引用非靜友元函數在某個類定義中用friend說明一個外部函數后,這個外部函數就可直接訪問該類的任何私有成員。則該外部函數稱為這個類的友元函數。采用友元的目的主要是為提高效率。顯然它破壞了類的封裝性。注意:在某個類中說明的友元函數并不是該類的成員函數。它可以是外部的一個獨立函數,也可以是另外一個類中的成員函數。12/19/202243類和對象友元函數在某個類定義中用friend說明一個外部函數后,這個classCFriend{
friendvoidgFunc1(CFriend&p);
//聲明友元函數private: voidfunc1(){cout<<"friend\n";}};友元為外部的獨立函數voidgFunc1(CFriend&p)//定義外部友元函數,使用類對象引用作參數//注:不是成員函數不加類名::{ p.func1();//友元的使用,調用私有成員 …}testFriendFunction.cpp12/19/202244類和對象classCFriend友元為外部的獨立函數voidgclassCFriendB;classCFriendA{public:intf1(CFriendB&b);//類中使用另一個類對象須先有其說明intf2(CFriendB&b);};classCFriendB{friendintCFriendA::f1(CFriendB&b);//把CFriendA中f1說明為友元private:staticintm;};intCFriendB::m=5;intCFriendA::f1(CFriendB&b){returnb.m;}//正確:
intCFriendA::f2(CFriendB&b){returnb.m;}//錯誤:友元為另一個類的成員函數testFriendFunction2.cpp12/19/202245類和對象classCFriendB;友元為另一個類的成員函數tes同函數一樣,類也可以聲明為另一個類的友元,稱為友元類。若A為B的友元類,則A類的所有成員函數都是B類的友元函數,都可以訪問B類的私有和保護成員。聲明的形式為:classB{
friendclassA; …};注意:1)友元關系是不能傳遞的。2)友元關系是是單向的。友元類testFriendClass.cpp12/19/202246類和對象同函數一樣,類也可以聲明為另一個類的友元,稱為友元類。cla類的作用域類的作用域(簡稱類域)是指類的定義中由一對花括號括起的部分。類的所有成員都在類的作用域中。類域區分符“::”來確定成員函數的類域,從而可在類外定義成員函數。同變量一樣,在類定義體和函數體外定義的對象為全局對象,而在類定義體內或在函數體內定義的對象為局部對象。全局對象的作用域是從定義它的位置開始直至文件的結束,而局部對象的作用域只在類作用域或函數體內。12/19/202247類和對象類的作用域類的作用域(簡稱類域)是指類的定義中由一對花括號括#include<iostream.h>intpp=0;classCScope{public:
intpp;voidrp(intpp);};voidCScope::rp(intpp){
::pp=11; //變量名前加域區分符給全局變量pp賦值this->pp=100;
//給數據成員賦值cout<<pp<<endl;}voidmain(){CScopea;a.rp(4);cout<<pp<<'\n'<<a.pp<<endl;}testScope.cpp12/19/202248類和對象#include<iostream.h>testSco第7章類與對象(一)面向對象的基本概念類的定義創建對象構造函數與析構函數對象數組this指針靜態成員友元類的作用域12/19/202249類和對象第7章類與對象(一)面向對象的基本概念12/16/2022面向對象的基本概念*1.面向對象與面向過程的區別:我要開車去新疆面向過程我開車,我過陜西,我過蘭州……面向對象我命令車去新疆車怎么去我不關心(封裝)12/19/202250類和對象面向對象的基本概念*1.面向對象與面向過程的區別:12/12.類(class)和對象(object)的概念對象是系統中用來描述客觀事務的一個實體,它通過“屬性attribute(數據成員)”和“行為behavior(成員函數、方法)”來分別實體的靜態屬性和動態屬性。類是具有共同屬性和行為的對象的抽象。對象是類的實例(instance)。學生A抽象類對象學生學號姓名學習()學生A學號=101姓名=TOM實例化12/19/202251類和對象2.類(class)和對象(object)的概念對象是系統中*3.類(對象)之間的關系關聯關系教師姓名教學(學生A)學生學號姓名學習()學校12/19/202252類和對象*3.類(對象)之間的關系關聯關系教師姓名教學(學生A)繼承關系(一般和特殊)xx是一種XX類的繼承層次12/19/202253類和對象繼承關系(一般和特殊)xx是一種XX類的繼承層次12/16/聚合關系(整體和部分)隊長隊員球隊聚集頭身體人組合12/19/202254類和對象聚合關系(整體和部分)隊長隊員球隊聚集頭身體人組合1多態車go()大卡車go()小汽車go()12/19/202255類和對象多態車go()大卡車go()小汽車go()12/16/202面向對象的設計思想有那些類(對象)?每一種類(對象)有哪些屬性和方法?類(對象)之間有哪些關系?12/19/202256類和對象面向對象的設計思想有那些類(對象)?12/16/20228類類的定義類的定義格式一般分為說明部分和實現部分。說明部分:是用來說明類中的成員,包含數據成員的說明和成員函數的說明。成員函數是用來對數據成員進行操作的,也稱為“方法”。實現部分:是用來對成員函數進行定義。12/19/202257類和對象類的定義類的定義格式一般分為說明部分和實現部分。12/16/說明部分的一般格式class類類型名{
public:公有成員說明
private:
私有成員說明};私有訪問權限,為默認值,可缺省公有訪問權限除本類中的成員函數及友元外,其他類外函數不能訪問。程序中的任何函數都可訪問12/19/202258類和對象說明部分的一般格式class類類型名私有訪問權限,為默認值例如:定義一個Person類,設Person具有的特征:屬性(姓名、年齡、性別),方法(輸出一個人的屬性);則對應著有4個成員:三個數據成員,一個成員函數。三個數據成員定義為私有成員,print成員函數定義為公有成員。則有:classCPerson{
public:voidprint();
private:charname[10];intage;charsex;};類名通常用C字母開始,以區別其他標識符12/19/202259類和對象例如:定義一個Person類,設Person具有的特征:屬性類的實現部分類的實現部分即定義它的成員函數,如在類說明內部定義,則方式與定義普通函數大體相同。若在類說明外部定義成員函數,則應使用類域運算符::(p21)指明該函數是哪個類中的成員函數。格式為:函數類型類名::成員函數名(形參表){函數體;}voidCPerson::print(){cout<<name<<age<<sex<<endl;}除特殊指明外,成員函數操作的是同一對象中的數據成員。不同的類允許有相同名稱的成員函數,因此,在類外定義成員函數的實現時,必須在成員函數名前加上所屬類名和作用域操作符“::”。12/19/202260類和對象類的實現部分類的實現部分即定義它的成員函數,如在類說明內部定當成員函數的規模較小時,可在類中定義成員函數,成為內聯成員函數。例:classCDate{
public:voidsetDate(intm,intd,inty)//置日期值{ month=m;day=d;year=y;} voidprint();
private:intmonth,day,year;};voidCDate::print(){cout<<year<<'.'<<month<<'.'<<day<<endl;}若將內聯成員函數定義在類說明之外則要加上inline。內聯成員函數12/19/202261類和對象當成員函數的規模較小時,可在類中定義成員函數,成為內聯成員函注意事項1.在類體中不允許對所定義的數據成員進行初始化。classCDate{public:…private:intyear(1998),month(4);…};2.類中的數據成員的類型可以是任意的,包括整型、浮點型、字符型、數組、指針和引用等,也可以是另一個類的對象。3.習慣將類的定義代碼放到一個頭文件中,以后若要使用則用文件包含命令包含。錯誤testClass\CreateClass.cpp12/19/202262類和對象注意事項1.在類體中不允許對所定義的數據成員進行初始化。錯誤創建對象1.對象的定義形式為:類名
對象名列表;
CDatedate1,date2;//定義兩個CDate類的對象date1和date2
CDate*pDate=&date1;
//定義一個指向date1對象空間的指針pDateCDate&rDate=date2;//定義一個引用對象rDateCDatedata[3];//定義一個data對象數組,其元素類型為CDate類定義了一個類只是定義了一種類型,它并不分配空間,不能進行操作。只有用它創建對象后,系統才為對象分配存儲空間。12/19/202263類和對象創建對象1.對象的定義形式為:定義了一個類只是定義了一種類型成員的訪問通過對象可以訪問類中的公有類型數據和成員函數。其使用方式為:
對象名.成員函數名對象名.數據成員例:date1.year=2002;date1.Print();用指針訪問對象公有成員:指針名->數據成員或指針名->成員函數(*指針名).數據成員或(*指針名).成員函數例:pDate->day=30;pDate->Print();(*pDate).day=30;(*pDate).Print();用引用訪問對象成員:引用名.數據成員或引用名.成員函數例:rDate.year=2008;rDate.Print();12/19/202264類和對象成員的訪問通過對象可以訪問類中的公有類型數據和成員函數。其使注意:在成員函數中訪問成員無須加對象名來作為前綴。如:voidCDate::print(){cout<<year<<'.'<<month<<'.'<<day<<endl;}在year等成員之前不能加對象名,在定義類時,成員函數是所有對象共享的代碼,不被某一個對象獨占。也無法確定類的對象名。注意12/19/202265類和對象注意:注意12/16/202217類和對象例一個完整的程序//CDate.hclassCDate{public:voidsetDate(intm,intd,inty)//置日期值{ month=m;day=d;year=y;} voidprint();private:intmonth,day,year;};voidCDate::print(){cout<<year<<'.'<<month<<'.'<<day<<endl;}12/19/202266類和對象例一個完整的程序//CDate.h12/16/202218續例一個完整的程序#include<iostream.h>#include"CDate.h"voidmain(){CDatedate1;date1.setDate(8,5,1996);date1.print();
//cout<<date1.year<<endl;/*CDate*pDate=&date1;pDate->print();*/}testClass\testCDate.cpp12/19/202267類和對象續例一個完整的程序#include<iostream.類的成員函數內聯函數:指定義在類體內的成員函數。外聯函數:指說明在類體內,定義在類體外的成員函數。類外定義的函數缺省情況下都是外聯函數,用關鍵字inline
可以強制轉換。
對于內聯成員函數,編譯時在所有調用該函數的地方將裝入實際的函數代碼。1.內聯函數和外聯函數12/19/202268類和對象類的成員函數內聯函數:指定義在類體內的成員函數。對于內聯成classCDate{public:voidsetDate(intm,intd,inty)//內聯函數之一{ month=m;day=d;year=y;}voidprint();private:intmonth,day,year;};inlinevoidCDate::print()//內聯函數之二{cout<<year<<'.'<<month<<'.'<<day<<endl;}12/19/202269類和對象classCDate12/16/202221類和對象2.設置參數的缺省值函數在定義時可以預先定義出形參的缺省值。調用時如果給出實參,則用實參初始化形參,如果沒有給出實參,則采用預先定義形參的缺省值。例如:voidsetDate(intm,intd=28,inty=2008);
//缺省參數按從右往左的方式或voidsetDate(intm,intd=28,inty=2008){…}在進行函數調用時,主調函數的實參與被調函數的形參按從左到右的位置結合。TestParaDefault.cpp12/19/202270類和對象2.設置參數的缺省值函數在定義時可以預先定義出形參的缺省值3.函數的重載函數的重載:出現在相同作用域的兩個函數,如果具有相同的名字而形參表不同,則稱為重載函數(overloadedfunction)。調用時,會根據不同的參數表選擇對應的成員函數。重載函數,必須:函數名相同,函數的作用域相同,函數的參數個數或參數類型不同。使用重載函數時應注意:⑴只有返回值不同,不能成為重載函數。
intmax(inta,intb);doublemax(inta,intb); //錯誤⑵使用帶缺省值的函數時,可能引發錯誤。如:
intmax(inta,intb=0);intmax(intc);當用一個實參調用該函數時,如max(2),則會出現調用歧義性12/19/202271類和對象3.函數的重載函數的重載:出現在相同作用域的兩個函數,如果構造函數和析構函數構造函數和析構函數都是類的成員函數,是特殊的成員函數,不能被調用而由系統自動調用/執行。構造函數名與類名相同;析構函數名為類名前加“~”。構造函數的功能是在創建對象時給對象分配內存空間,并可使用給定值來初始化對象。析構函數的功能是用來釋放一個對象的已分配空間。并可在對象被清除前,完成一些清理工作。12/19/202272類和對象構造函數和析構函數構造函數和析構函數都是類的成員函數,是特殊對前面的日期類進行修改,并將定義存放在CDate1.h文件中。如:classCDate1
{public:CDate1(inty,intm,intd);~CDate1();voidprint();private:intyear,month,day;
};函數名與類名一致,無類型但可有參數名字與類名一致,前有~,無類型無參數12/19/202273類和對象對前面的日期類進行修改,并將定義存放在CDate1.h文件中CDate1::CDate1(intm,intd,inty){month=m;day=d;year=y;cout<<"Constructorcalled.\n";}CDate1::~CDate1(){cout<<"Destructorcalled.\n";}voidCDate1::print(){cout<<year<<"."<<month<<"."<<day<<endl;}與其他成員函數定義一樣,兩種函數的定義可放在類體內,也可放在類體外12/19/202274類和對象CDate1::CDate1(intm,intd,int#include<iostream.h>#include"CDate1.h"voidmain(){CDate1today(2007,4,1),tomorrow(2007,4,2);cout<<"todayis";today.print();cout<<"tomorrowis";tomorrow.print();}執行程序后,輸出結果為:函數結束時,自動調用析構ConstructorCalled.ConstructorCalled.todayis2007.4.1tomorrowis2007.4.2Destructorcalled.Destructorcalled.12/19/202275類和對象#include<iostream.h>函數結束時,自動調構造函數的特點有:程序中一般不直接調用構造函數,在創建對象時系統自動調用構造函數。構造函數可以重載,即可定義多個參數個數不同的函數構造函數有隱含的返回值,并由系統內部使用析構函數的特點有:一個類中只能定義一個析構函數,即不能重載析構函數可以被調用,也可系統調用被自動調用的情況有兩種:在一個函數體內定義的一個對象,當函數結束時用new運算符動態創建的一個對象,在使用delete釋放時12/19/202276類和對象構造函數的特點有:12/16/202228類和對象缺省構造函數和缺省析構函數在類定義中可以不定義任何構造函數,這時編譯器會自動生成一個不帶參數的缺省構造函數。其格式為:
<類名>::<缺省構造函數名>(){}則在程序中定義一個對象而未指明初始化時,編譯器便按缺省構造函數來初始化該對象。若定義了構造函數,則編譯器就不會再生成缺省構造函數,必須使用定義的構造函數創建對象。同理,若一個類中未定義析構函數,編譯系統也生成一個缺省析構函數。其格式為:<類名>::~<缺省析構函數名>(){}這也是前面的程序中可以沒有構造和析構函數的原因12/19/202277類和對象缺省構造函數和缺省析構函數在類定義中可以不定義任何構造函數,classCConstruct{ public:CConstruct(intx,inty);CConstruct(); voidprint(); private: intm1,m2;};CConstruct::CConstruct(intx,inty){ m1=x; m2=y;}CConstruct::CConstruct(){ m1=0; m2=0;}TestConsOverLoad.cpp例:12/19/202278類和對象classCConstructTestConsOverLovoidCConstruct::print(){cout<<m1<<","<<m2<<endl;}voidmain(){ CConstructc2; CConstructc1(3,4);c1.print();}不帶參數創建對象,調用無參構造函數12/19/202279類和對象voidCConstruct::print()不帶參數創拷貝初始化構造函數構造函數除可以用基本數據類型初始化對象外,還可以使用已存在的同類型的對象即類類型的對象來初始化正在創建的對象。為此,必須在類中定義一個特殊的構造函數來完成這個工作,這個構造函數被稱為拷貝初始化構造函數。格式為:<類名>::<拷貝初始化構造函數名>(<類名>&<引用名>){…}如:student::student(student&s){…}每個類中必須有一個。若類中未說明,則編譯系統會自動生成缺省函數。12/19/202280類和對象拷貝初始化構造函數構造函數除可以用基本數據類型初始化對象外,classCMyClass{ public: CMyClass(intx); CMyClass(CMyClass&c); private: intmember;};CMyClass::CMyClass(intx){member=x;}CMyClass::CMyClass(CMyClass&c){ cout<<"copyconstructorcalled"<<endl; member=c.member;}拷貝初始化構造函數TestCopyConstructor.cpp12/19/202281類和對象classCMyClass拷貝初始化構造函數TestCo拷貝初始化構造函數被自動調用有三種情況:一、是用一個已知對象初始化一個新對象時。二、是以值調用方式向一個函數傳遞對象參數時。三、當對象作為函數返回值時。CMyClassfun(CMyClassd);voidmain(){ CMyClassb(3);
CMyClassc(b); CMyClasss=fun(c);}CMyClassfun(CMyClassd){ returnd;}12/19/202282類和對象拷貝初始化構造函數被自動調用有三種情況:12/16/2022內存解析member:3bMyClass(intx)MyClass(MyClass&c)cmember:3member:3dmember:3*member:3s12/19/202283類和對象內存解析member:3bMyClass(intx)MyC對象數組對象數組:一個數組中的每個數組元素都為同一類的對象。對象數組的定義有以下幾種形式:類中只有無參的構造函數類名數組名[常量表達式];例:CDate2objArray[4];類中只有需要參數的構造函數類名數組名[常量表達式]={構造函數名(參數表),…,構造函數名(參數表)};例:CDate2objArray[2]={CDate1(2002,3,4),CDate1(2008,5,26)};類中有無參的構造函數和有參的構造函數12/19/202284類和對象對象數組對象數組:一個數組中的每個數組元素都為同一類的對訪問數組元素對象的成員objArray[1].print()或(objArray+1)->print()testObjectArray.cpp12/19/202285類和對象訪問數組元素對象的成員testObjectArray.cpp每一個類的非靜態成員函數中的都有一個指針形參this,用于指向正在操作該成員函數的對象。例如:classCDate3{ public: CDate3(inty,intm,intd); voidprint(CDate3*t); voidprint(); private: intyear,month,day;};CDate3::CDate3(inty,intm,intd){ year=y;month=m; day=d;}this指針testThis.cpp12/19/202286類和對象每一個類的非靜態成員函數中的都有一個指針形參this,用于voidCDate3::print(CDate3*t){cout<<t->year<<"."<<t->month<<"."<<t->day<<endl;}voidCDate3::print(){cout<<this->year<<"."<<this->month<<"."<<this->day<<endl;}#include<iostream.h>#include"CDate3.h"voidmain(){ CDate3objThis(2008,4,23);objThis.print(&objThis);objThis.print();}隱含的指針形參this12/19/202287類和對象voidCDate3::print(CDate3*t)隱靜態成員定義類時,可用關鍵字static聲明的數據成員或成員函數稱為靜態成員,包括靜態數據成員和靜態成員函數。靜態數據成員是在編譯時被創建,與對象是否存在無關,其內存空間為數據區,其生命期一直到程序結束。靜態數據成員必須在類外初始化:
數據類型類名::成員名=初始值;靜態成員函數屬于類,而不是對象成員(無this指針用來存放對象的地址),不能直接引用具體對象中的非靜態成員。須使用(對象名.成員名)來引用。可以通過對象名或類名來訪問靜態成員。12/19/2022
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 工業園區規劃與產業升級研究
- 工業大數據在智能工廠的應用
- 工業機器人與智能制造的關系研究
- 工業機器人技術及其應用案例分享
- 工業機器人發展現狀及趨勢分析
- 工業自動化系統的能效管理與優化
- 工業設計中的創新設計思維研究
- 工業自動化技術及裝備升級改造
- 工業自動化及智能制造的發展趨勢與機遇
- 30人團隊管理制度
- 黨課課件含講稿:《關于加強黨的作風建設論述摘編》輔導報告
- GB/T 19023-2025質量管理體系成文信息指南
- 2025中考歷史高頻點速記大全
- 2025年北京西城區九年級中考二模英語試卷試題(含答案詳解)
- T/CECS 10378-2024建筑用輻射致冷涂料
- 數據驅動的古氣候研究-洞察闡釋
- 護理糾紛處理制度
- 護理實習入科教育
- 2025年湖北省武漢市中考化學模擬練習卷(含答案)
- 2024年自然資源部所屬單位招聘筆試真題
- 《2025-0015T-FZ 智能制造 服裝定制 人體測量實施要求》知識培訓
評論
0/150
提交評論