安全傳輸平臺項目-第02天keymngserver重構硬件擴展-c基礎課程講義_第1頁
安全傳輸平臺項目-第02天keymngserver重構硬件擴展-c基礎課程講義_第2頁
安全傳輸平臺項目-第02天keymngserver重構硬件擴展-c基礎課程講義_第3頁
安全傳輸平臺項目-第02天keymngserver重構硬件擴展-c基礎課程講義_第4頁
安全傳輸平臺項目-第02天keymngserver重構硬件擴展-c基礎課程講義_第5頁
免費預覽已結束,剩余146頁可下載查看

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

C++傳智掃地1、C++C的擴簡單的C++程求圓的周長和面輸入半徑2*π*r;計算面積=π*r2;方法1:用結構化方法編程,求圓的周長和面//countthegirthandareaofcircleusingnamestd;voidmain(){doubler,girth,areaconstdoublePI=3.1415cout<<"Pleaseinputradius:\n";//操作符重載cin>>r; girth=2*PI*r;area=PI*r*r;cout<<"radius="<<r<<endl;cout<<"girth="<<girth<<endl;cout<<"area="<<area<<endl;}方法2:用面向對象方法編程,求圓的周長和面usingnamestd;class doubleradius成員變量public://類的控制voidSet_Radius(doublerradiusrdouble radiusdoubleGet_Girth() {return 2*3.14f*radius;}//通過成員函數獲取成員變量doubleGet_Area() {return 3.14f*radius*radius;}}void{CircleA,B;//用類定義對象A.Set_Radius(6.23類的調用cout<<"A.Radius="<<A.Get_Radius()<<endlcout<<"A.Girth="<<A.Get_Girth()<<endl;cout<<"A.Area="<<A.Get_Area()<<endl;B.Set_Radius(10.5);cout<<"B.radius="<<B.Get_Radius()<<endl;cout<<"B.Girth="<<B.Get_Girth()<<endl;cout<<"B.Area="<<B.Get_Area()<<endl;}初學者易犯錯誤模usingnamespacestd;//c++名空class{doubledoublepi=3. doublearea=pi*r*r;int{circlecoutarea"endl;cin>>pi.r;coutpi.areaendl;//亂碼return} 程序設計方法的發展歷面向過程的結構化程序設計方。面向對象的將數據及對數據的操作方法封裝在一起,作為一個相互依存、不可分離的整體類通過一個簡單的外部接口,與外界類封面向對象的軟件工面向對象的軟件工程是面向對象方法在軟件工程領域的全面應用。它包括面向對象的分析面向對象的設計面向對象的編程面向對象的測試面向對象的軟件+軟件可性構建的軟件用戶需C語言和C++語言關C語言是在實踐的過程中逐步完善起來的C當面向過程方法論越來越多的缺陷的時候,業界開始考慮在工程項目中引入面向對C+面向對象方法論===》ObjectiveCCC++C++CCC++CCC++并不會影響原有的C語言知識,相反會根據加深對C的認知;學習C++可以接觸到的軟件設計方法,并帶來的機會。C++是一種更強大的C,通過學習C++能夠掌握的軟件設計方C++是Java/C#/D等現發語言的基礎,學習C++后能夠快速掌握這些語C++C++C的加namespace命名空C++命名空間基本namespace,是指標識符的各種可見范圍。C++標準程序庫中的所有標識符都被定stdnamespace中。<iostream>和<iostream.h>include為.h的頭文件c++在帶.h后綴的頭文件里,c++C區別開,也為了正確使用命名空間,規定頭文件不使用后綴.h。因此,c++實現;當使用<iostream>spaceC++1std::ostreamostreamstd::cout<<std::hex<<3.4<<2usingusingstd::coutusingstd::endlusingstd::cin;cout<<std::hex<<3.4<<3usingnamespacestd;usingnamespacestd;這樣命名空間std內定義的所有標識符都有效(。就好像它們被為全局變量一樣。那么以上語句可以如下寫:cout<<hex<<3.4<<endl;稱或函數名時就很有可能和標準庫中的某個名字相同。所以為了避免這種情況所造成的名字,就把標準庫中的一切都被放在名字空間d中。但這又會帶來了一個新問題。++以就有了<iteam.h>和ioteam>等等這樣的頭文件,一個是為了兼容以前的++代碼,d前的頭文件區別,一般不加".h"C++命名空間定義及使用語C++庫時,這些標識符名發生,stdc++標準命名空間,c++std中,比如標準庫iostream、vector等都定義在該命名空間中,使用時要加上using(usingnamespace 或using指(std::string、C中名空CC語言中所有的全局標識符共享同一個作用域標識符之間可能發生C++不同命名空間中的標識符可以同名而不會發生namespacename{ C++使用整個命名空間:usingnamespacename;使用命名空間中的變量:usingname::variable;C++命名空間編程實namespace{inta=}namespace{inta=namespace{struct{charname[10];intage;}}int{usingnamespaceusingprintf("a=%d\n",printf("a=%d\n",NameSpaceB::NameSpaceC::Teachert2Teachert1={"aaa",3};printf("=%s\n",);printf("t1.age=%d\n",t1.age);return0;}結coutusingnamespacestd,需要這樣做。std::cout。C++命名空間的定義:namespacename usingnamespacenamespce“實用性”增#include"iostream"usingnamespacestd;//Cint{inti=intk;return0;}//registera//cregisterc++registerregister關鍵字請求“編譯器”將局部變量于寄存器Cregister變量地址C++register關鍵字C++registerC++registerC++編譯器發現程序中需要取register變量的地址時,register對變量的變得無效Cregisterint{registerinta=printf("&a=%x\n",&a);return}其他補充:請閱讀《register關鍵字課外閱讀.docx變量檢測增C語言中,重復定義多個同名的全局變量是合法的C++中,不允許定義多個同名的全局變量C語言中多個同名的全局變量最終會被到全局數據區的同一個地址空間intintg_var=C++直接這種二義性的做法intmain(intargc,char{printf("g_var=%d\n",g_var);return0;}struct類型加structCstruct定義了一組變量的集合,CC++struct是一個新類型的定義struct{charname[100];intage;intmain(intargc,char{Students1={"wang",1};Students2={"wang2",2};return0;}C++中所有的變量和函數都必須有類C++CC++f的返回值是什么類型,參數又是什么類型?g可以接受多少個參數?//更換成.cpp{printf("i=%d\n",}{return}intmain(intargc,char{printf("g()=%d\n",g(1,2,3,4,return0;}Cintf( intf(void)int的無參函數int );intf(void)intC++4.2-4.6屬于語法級別的增強Bool類型關鍵C++中的類C++CboolC++booltruefalseboolboolbittrue1false0booltrue(0)false(0)C++0true,0intmain(intargc,char{intboolb=printf("b=%d,sizeof(b)=%d\n",b,b=a=printf("a=%d,b=%d\n",a,b=-a=printf("a=%d,b=%d\n",a,a=b=printf("a=%d,b=%d\n",a,b=printf("b=%d\n",return0;}三目運算符功能增三目運算符CC++編譯器的int{inta=10;intb=////(a<b?a:b)=printf("a=%d,b=%d\n",a,b);return}結1)CC++C(a<b?1:b)=3)CC++C中的三目運算法當左值呢?C/C++const基礎知識(用法、含義、好處int{constinta;intconstconstint*c;int*constd;constint*constereturn}Intfunc1(const初級理解:const是定義常量==》const////c是一個指向常整形數的指針(所指向的內存數據不能被修改,但是本身可以修//第四個d常指針(指針變量不能被修改,但是它所指向內存空間可以被修改//e一個指向常整形的常指針(指針和它所指向的內存空間,均不能被修改Const//1//2ConstC中“貨int{constinta=int*p=printf("a===>%d\n",*p=printf("a===>%d\n", return}C++const當碰見常量時,在符號表中放入常量=問題:那有如何解釋取地址編譯過程中若發現對const使用了extern或者&操作符則給對應的常量分配空(兼C)int&a1(err&constint&aC++constC++編譯器雖然可能為const常量分配空間,但不會使用其空間中的值CconstC語言中const變量是只讀變量,有自己的空C++const可能分配空間,也可能不分配空const常量為全局,并且需要在其它文件中使用當使用&const常量的地址const和#define相同之////#defineN10intmain(){constinta=constintb=intarray[a+b]={0};inti=0;for(i=0;i<(a+b);{printf("array[%d]=%d\n",i,}return0;}C++constC中變量(只讀constconst和#define的區C++中的const常量類似定constintc5;#definec5C++const常量與宏定義不同const//func1afunc2//func1bfunc2void{#definea10constintb=20;//#undef #}void{printf("a=%d\n",//printf("b=%d\n",}int{}結CconstC語言中const變量是只讀變量,有自己的空C++const可能分配空間,也可能不分配空當const常量為全局,并且需要在其它文件中使用,會分配空間當使用&操作符,取const常量的地址時,會分配空間當constint&a=10;const修飾時,也會分配空6專題講1(普通變量名實質上是一段連續空間的別名,是一個標號(門牌號)通過變量的名字可以使用空1概 在C++中新增加了的概 可以看作一個已定義變量的別 的語法:Type&name=d)做函數參數那?(作為函數參數時不進行初始化void{inta=10;//c編譯器分配4個字節內存。a內存空間的別名int&b=a; a=11{int*p=*p=printf("a%d} =printf("a:%db:%d",a,b);}2是C++的概問題:C中可以編譯通過嗎int{inta=int&b=a;//int*constb=&ab=11;//*b=11;return}結論:請不要用C的語法考慮3做函數參普通在時必須用其它的變量進行初始化作為函數參數時不進行初始//05復雜數據類型的struct{charname[64];intage;{}//pT是t1,相當于修改了t1voidprintfT2(Teacher&pT){}voidprintfT3(TeacherpT){pT.age45;只會修改pT,不會修改t1}void{Teachert1;t1.age=printfT2(t1);//pT是t1的別名printf("t1.age:%dn"t1.age33printfT3(t1);//pT是形參,t1copy一份數據給pT //--->pT=t1printf("t1.age:%d\n",t1.age);//35 return;}4的意1)作為其它變量的別名而存在,因此在一些場合可以代替指2)相對于指針來說具有更好的可讀性和實用5本質思思考1:C++int{inta=int&b=//b是a的別名,請問c++編譯器后面做了什么工作b=cout<<"b---printf("a:%d\n",printf("b:%d\n",printf("&a:%d\n",printf("&b:%d\n",&b);//請思考:對同一內存空間可以取好幾個名字嗎return}單獨定義時,必須初始化;說明很像一個常思考2:普通有自己的空間嗎structTeacer{int&a;int&b;int{printf("sizeof(Teacher)%d\n",sizeof(Teacer));return}是一個有地址,是常量。。。。char*const6的本Type&nameType*constC++編譯器在編譯過程中使用常指針作為的內部實現,因此所占用的空間從使用的角度,會讓人誤會其只是一個別名,沒有自己的空間。這是C++Int{intx =10;}1(一個實參一個形參23*p7結1)在實現上,只不過是把:間接賦值成立的三個條件的后兩步和二為//當實參傳給形參的時候,只不過是c++編譯器幫我們程序員手工取了一個實參地址,傳給了形參(常量指針)2)當我們使用語法的時,我們不去關心編譯器是怎么做當我們分析奇怪的語法現象的時,我們才去考慮c++編譯器是怎么做函數返回值是(當左值C++使用時的難點:當函數返回值為時不能成為其它的初始值可以成為其他的初始int{inta;a=10;return}C++鏈式編程中,經常用到int{inta;a=10;return}int&getAA2(){inta;a=10;return}int*{inta;a=10;return}返回值是static變量,當intj(){staticinta=10;a++;printf("a:%d\n",a);returna;}int&{staticinta=10;a++;printf("a:%d\n",a);returna;}int{staticinta=10;a++;printf("a:%d\n",a);return&a;}void{j()//11=//*(a>b?&a:&b)=//當被調用的函數當左值的時候,必須返回一個j1(100;編譯器幫我們打造了環境*(j2()200;}返回值是形參,當 g1(int{*p=return} g2(int*p){*p=return}//當我們使用語法的時候,我們不去關心編譯器是怎么做voidmain23(){inta1=10;a1=g2(&a1);int&a2=g2(&a1);//用去接受函數的返回值,是不是亂碼,關鍵是看返回的內存printf("a1:%d\n",printf("a2:%d\n",}返回值非基礎類struct{charname[64];intage;//如果返回不是基礎類型,是一個類,那么情況非常賦值。涉及到copy構造函數和=struct{charname[64];intage;//如果返回不是基礎類型,是一個類,那么情況非常賦值。涉及到copy構造函數{}指針#include"iostream"usingnamespacestd;struct{charname[64];intage;{Teacher*p=(Teacherif(p{return-}memset(p,0,p->age= =p;return}//指針的而int {myp->age=34;return}void{Teacher*p=printf("age:%d\n",p->age);}常使用變量初始化const思考costint&abPKconstint&a????問題:const在C++中可以constconstType&name=var;const讓變量擁有只讀屬案例int{inta=constint&b=//int*p=(int*)&b;b=11;//err//*p11;只能用指針來改變printf("a:%d\n",a);printf("b:%d\n",printf("&a:%d\n",printf("&b:%d\n",return0;}案例void{inta=constint&b=a;//const使用變量a初始a=//b=12;//通過修改a,對不起修改不}struct{charname[64];intage;voidprintTe2(constTeacher1*const{}//const讓變量(所指內存空間)擁有只讀屬voidprintTe(constTeacher1{//t.age=}void{Teacher1t1;t1.age=33;}使用字面量常量初始化const}}//int&a119;如果不加const編譯失constint&a=19;printf("&a:%d\n",&a);void{constintb=10;printf("b:%d",&b);2、用常量對綜合void{//普通inta=10;int&b=//常量:讓變量只讀屬constint&c=//常量初始化分為兩//1用變量初始化常量{intx=constint&y=x;printf("y:%d\n",y);}//2用常量初始化常量{//int&m=10;//是內存空間的別名字面量10沒有內存空間沒有方法做用constint&m=}cout<<"return;}const結1)Const&inte constint*conste2)普通相當于int*conste1間,并將名作為這段空間的別名4const修飾綜合練int&int&{staticinta=0;returna;}int&{inta=0;return}int{inta=int&b=g();j()=10;printf("a=%d\n",printf("b=%d\n",b);printf("f()=%d\n",f());return}}7C++C的函數擴inline內聯函C++constconstintA= #defineAC++中是否有解決方案替代宏代碼片段呢?(C++C++中使用inline關鍵字內聯函內聯函數時inline關鍵字必須和函數定義結合在一起否則編譯器會直接忽略內聯請#include"iostream"usingnamespacestd;#defineMYFUNC(a,b)((a)<(b)?(a):inlineintmyfunc(inta,int{returna<b?a:}int{inta=1;intb=//intc=myfunc(++a,b); intc=MYFUNC(++a,b);printf("a=%d\n",printf("b=%d\n",printf("c=%d\n",return0;}inlineintmyfunc(inta,intb)C++C++C++4內聯函數是對編譯器的一種請求,因此編譯器可能這種請求現代C++編譯器能夠進行編譯優化,因此一些函數即使沒有inline,也可能被編譯器C++如:g++中的attribute((always_inline))C++函數內聯必須在調用語句之編譯器對于內聯函數的限制并不是,內聯函數相對于普通函數的優勢只是省去了inline默認參C++中可以在函數時為參數提供一個默認值voidmyPrint(intx={printf("x:%d",}//voidprintAB(intx={printf("x:%d\n",}//voidprintABC(inta,intb,intx=3,inty=4,intz={printf("x:%d\n",}intmain62(intargc,char{return0;}函數占位參占位參數只有參數類型,而沒有參數名intfunc(inta,intb,int{returna+}int{//func(12);printf("func(1,2,3)=%d\n",func(1,2,return0;}默認參數和占位參C//C++可以占位符參數,占位符參數一般用于程序擴展和對C代碼的兼intfunc2(inta,intb,int={returna+}void{func2(1,2);func2(1,2,}函數重載函數重載概函數重載(Function//intfunc(int{return}intfunc(inta,int{returna+}intfunc(constchar*{return}int{intc=c=printf("c=%d\n",c);c=func(1,2);printf("c=%d\n",c=printf("c=%d\n",printf("Pressentertocontinue...");return}函數重載的調用函數重載遇上函數默認參intfunc(inta,intb,intc={returna*b*}intfunc(inta,int{returna+}//1intfunc(int{returna+}int{intc=cfunc(12);//printf("c=%d\n",printf("Pressentertocontinue...");return}函數重載和函數指針結intfunc(intx)//int(int{return}intfunc(inta,int{returna+}intfunc(constchar*{return}typedefint(*PFUNC)(inta);//int(inta)intmain(){intc=PFUNCp=c=printf("c=%d\n",printf("Pressentertocontinue...");return}函數重載、重寫、重定附附錄1:C++語言對C語言擴充和增強的幾點具體體registerCPU內存尋址,以提高效率。注意是盡可能,不是絕對。你想想,一個CPU的寄存器也register變量,它累死也可能不能全部一、身邊的小太 寄存見過就麻煩大了。^_^,大家都看過古裝戲,那些們要閱讀奏章的時候,大臣總是先將奏章交給旁邊的小太監,小太監呢再交給處理。這個小太監只是個中轉好,那我們再聯想到我們的CPU。CPU不就是我們的么?大臣就相當于我們的內存,數據從他這拿出來。那小太監就是我們的寄存器了(CPU高速緩存區)。數據從內存里拿出來先放到寄存器,然后CPU再從寄存器里數據來器沒這么自覺,它從不主動干什么事。一個可能有好些小太監,那么一個CPU也可CPU擁有寄存器的數量不一樣。為啥要這么麻煩啊?速度!就是因為速度。寄存器其實就是一塊一塊小的空CPU,CPU一伸二、舉將其保存在CPU的寄存器中,以加快其速度。例如下面的內存塊拷貝代碼,#ifdefNOSTRUSIGNmemcpy(d,s,l){registerchar*d;registerchar*s;registerinti;while(i--)*d++=}三、使register首先,register變量必須是能被CPU所接受的類型。這通常意味著register變量數),registerregister寄存器不能再用于其它目的;或者變量被使用的次數不夠多,不足以裝入和變量所CregisterCregister復雜數據類型做函數參數設計一個類,設計一個學生類,屬性有和學號,可以給和學號賦值可以顯示學生的和學2、類和對前C++C++===類和對基本概定義Teacher類,打印Teacher的信息(把類的和類的實現分開類的封封裝備注:有2層含義(把屬性和方法進行封裝對屬性和方法進行控制C++成員函數,C++類成員的控在C++中可以給成員變量和成員函數定義級Public修飾成員變量和成員函數可以在類的內部和類的外部被Private修飾成員變量和成員函數只能在類的內部被//類是把屬性和方法封裝同時對信息進行控classCircle{doubler;doubledouble{return}voidsetR(double{r=}doublegetS()增加功能時,是在修改類,{s=3.14f*r*r;returns;}intstructclass關鍵字區structclassC++面向對象程序設計舉目標:面向過程向面向對象思想轉初學者要仔細體會類和對象之間的關系,并通過適當練習鞏固和提高案例1 設計立方體類),求出立方體的面積和體積求兩個立方體,是否相等(全局函數和成員函數案例2 (AdvCircle,(Point,案例 對于第二個案例,類的和類的實現分作定義一個Point2Rectangle的矩形類,其屬性為矩形的左下角與右上角兩個點3Treeages(樹齡grow(intyears)agesyears,age()treeages對象的構造和析數據成員是不能在類時初始化的。構造和析構函1構造函數和析構函數有關構造函1++沒有任何返回類型的2有關析構函3)C++數析構函數沒有參數也沒有任何返回類型的2C++編譯器構造析構方案PK對象顯示初始化方面向對象的思想是從生活中來,、車出廠時,是一樣的publicinitialize函數;initialize函數進行初始化。initialize一旦由于的原因,對象沒有初始化,那么結果將是不確定的//#include"iostream"usingnamespacestd;initclass{intintgetM()const{returnm;}voidsetM(intval){m=val;intintgetN()const{returnn;}voidsetN(intval){n=val;intinit(intm,int{this->m=m;this->n=n;return0;}int{intrvTest21t1; Test21t2;//t1.init(100,//t2.init(300,cout<<t1.getM()<<""<<t1.getN()<<endl;cout<<t2.getM()<<"http://定義對象數組時,沒有機會進行顯示初始returnrv;}構造函數的分類及調C++classTest{inta;int{;}Test(inta,intb){;}{;}voidinit(int_a,int{a=b=}無參數構造函Testt1,有參構造函classTest5{inta;Test5(inta){}Test5(inta,int{printf("\na:%db:%d",a,}int{Test5t1(10);//c++Test5t2(20,10c++Test5t3Test5(30return0;}拷貝構造函數調用時#include"iostream"usingnamespacestd;class#include"iostream"usingnamespacestd;class{AA({}AA(int_a{a=}AA(constAA{cout<<"我也是構造函數,我是通過另外一個對象obj2,來初始化 a=obj2.a+10;}{}void{printf("a:%d\n",}intvoidObjPlay01(){AAa1;//1AAa2a1;定義變量并初始化//a2a1;a1來=a2}voidObjPlay02(){AAa1(10//1AAa2(a1////a2a1;a1來=a2copy}//3#include"iostream"usingnamespacestd;class{Location(intxx=0,intyy=0{X=xx Y=yy cout<<"ConstructorObject.\n"}Location(constLocation&p {X=p.X Y=p.Y cout<<"Copy_constructorcalled."<<endl}{cout<<X<<","<<Y<<"Objectdestroyed."<<endl} GetX(){returnX;} intGetY(){returnY;}private: X,Y;}//altf8voidf( p{cout<<"Funtion:"<<p.GetX()<<","<<p.GetY()<<endl}void{LocationA(1,2); f(A);}void{}4#include"iostream"usingnamespacestd;classLocation{Location(intxx=0,intyy=0{X=xx Y=yy cout<<"ConstructorObject.\n"}Location(constLocation&p //構造函{X=p.X Y=p.Y cout<<"Copy_constructorcalled."<<endl}{cout<<X<<","<<Y<<"Objectdestroyed."<<endl} GetX(){returnX;} intGetY(){returnY;}private: X,Y;}//altf8voidf( p{cout<<"Funtion:"<<p.GetX()<<","<<p.GetY()<<endl}Location{LocationA(1,2);returnA;}//=//對象的去和留,關鍵看,返回時如何void{//若返回的對象,賦值給另外一個同類型的對象,那么對象會被析//Location//B= //用對象賦值給B對象,然后對象析//若返回的對象,來初始化另外一個同類型的對象,那么對象會直接轉成新LocationB=}void{}默認構造函成員變量的值構造函數調用規則研c+編譯器會提供默認無參構造函數和默認拷貝當類中定義了拷貝構造函數時,c++構造析構階段性總C++========》1深拷貝和淺拷默認構造函數可以完成對象的數據成員值簡單的對象的數據資源是由指針指示的堆時,默認構造函數僅作指針值淺拷貝問題拋出和分淺拷貝程序C++提供的解決方copyclass{Name(constchar{size=pName=(char*)malloc(size+1);strcpy(pName,pname);}Name(Name{//objpName=(char*)malloc(obj.size+1);strcpy(pName,obj.pName);size=}{if(pName!=NULL){pName=NULL;size=0;}}{if(pName!={pName=NULL;size=0;}//obj3來=pName=(char*)malloc(obj3.size+1);strcpy(pName,obj3.pName);size=}char*pName;intsize;//=void{Name Nameobj2obj1obj2Name obj2obj3;號操作}void{}多個對象構造和析1對象初始化列2constconstintm當類成員中含有一個const對象時,或者是一個時,他們也必須要通過成員初始化語則Constructor::Contructor():m1(v1),m2(v1,v2),{//someotherassignment}1C++21C++22constconstintm當類成員中含有一個const對象時,或者是一個時,他們也必須要通過成員初始化列//#include"iostream"usingnamespacestd;class{ABC(inta,intb,int{this->a=a;this->b=b;this->c=c;printf("a:%d,b:%d,c:%d\n",a,b,c);printf("ABCconstruct..\n");}{printf("a:%d,b:%d,c:%d\n",a,b,c);printf("~ABC()..\n");}inta;intb;intclass{{}{}ABCabc1;c++abc1ABCabc2;constintint{MyDmyD;return0;}int{return0;}構造函數和析構函數的調用順序研構造函數與析構函數的調用順構造函數和析構函數綜合練1構造析綜合訓demo10_構造析構練習強化.cpp(講解)2對象強化訓1)對象生命周2)對象的去和3對象強化訓demo11_對象練習強化對象的動態建立和釋newdelete基本語的插入與刪除。在C語言中是利用庫函數malloc和free來分配和撤銷內存空間的。C++提供newdeletemallocfree函數。newdeleteC語言兼容,C++mallocfreemallocfreenewdelete運算符。newnewint;//開辟一個存放整數的空間,返回一個指向該空間的地址(即指針newint(100);//100,返回一個指向該存newchar[10];//開辟一個存放字符數組(10個元素)newint[5][4];//開辟一個存放二維整型數組(5*4)float*p=newfloat(3.14159);//開辟一個存放單精度數的空間,并指定該實數的初值為3)newdelete運算符使用的一般格式為:用newnewNULL,用戶可以根據該指針的值判斷分配空間是否成功。4)類對象的動態建立和釋C++newdeleteBox*pt;//Boxpt=newBox;//pt中存放了新建對象的起始地址在程序中就可以通過pt這個新建的對象。如cout<<pt->height;//heightcout<<pt->volume//volumeC++newBox*pt=newheight,widthlength12,15,18。調用對象既可以通過對象new00行有關處理。但C++標準仍然允許在出現new故障時返回0指針值。當前,不同的編譯系統new故障的處理方法是不同的。newdeletedeletept;ptpt編程 mallocfree函 c關鍵 newdelete操作符 c++的關鍵//2new在堆上分配內存////3newmalloc深入分析結論 malloc不會調用類的構造函Free靜態成員變量成員函靜態成員變static可以用于說明一個類的成員, static這個static成員usingnamespacestd; { num;//與定義靜態數據成public setnum(inti){num=i; //成員函數靜態數據成 shownum(){cout<<num<<'\t';} counter::num=0;//與定義靜態數據成voidmain a,ba.shownum();//調用成員函數私有靜態數據成b.shownum()a.setnum(10)a.shownum()b.shownum()}從結果可以看出,的是同一個靜態數據成//例5- 使用公有靜態數據成 {publiccounter(inta){mem=a;int // Smem;//} counterSmem1 //void counterc(5);inti;for(i=0;i<5;i++{counter::Smem+=icout<<counter::Smem<<'\t' //靜態成員變量方法}cout<<"c.Smem="<<c.Smem<<endl;//靜態成員變量方法1cout<<"c.mem="<<c.mem<<endl;}靜態成員函this“”作限定詞,或通過對象調用綜合訓C++面向對象模型初前C++2“c++中,通過抽象數據類型(datatype,ADTC++類中有兩種成員數據onstaticonstatic、基礎知C++class從面向對象理論出發,將變量(屬性)和函數(方法)集中定義在一起,用于描C++編譯器如何完成面向對象理論到計算機程序的轉化換句話:C++#includeusingnamespacestd;classC1{inti; intj;//4intk; };class{intinti;intj; intk; staticintm;//4intgetK()const{returnk;}voidsetK(intval){k=val; };//1216struct{inti;intj;int};struct{inti;intj;intstaticint};int{printf("c1:%d\n",printf("c2:%d\n",printf("s1:%d\n",printf("s2:%d\n",}編譯器對屬性和方法的處理機1)C++類對象中的成員變量和成員函數是分開普通成員變量:于對象中,與struct變量有相同的內存布局和字節對齊方式靜態成員變量:于全局數據區中成員函數:于代碼段中換句話說:intgetK()constreturnk;obj1、obj2、obj32)C++總1、C++類對象中的成員變量和成員函數是分開的。C語言中的內存四區模型仍然有2、C++中類的普通成員函數都隱式包含一個指向當前對象的this指針3this指1this指針來解決。2constconst修飾的是誰全局函PK成員函1thisvoidprintAB()===》voidprintAB(Test*pthis)3、函數返回元素和返回{this->a=this->a+t2.getA();this->b=this->b+return*this*this}/{//t3Testt3(this->a+t2.getA(),this->b+t2.getB());returnt3;}voidadd3(Test&t2/*this{//t3Testt3(this->a+t2.getA(),this->b+t2.getB())//return}66.1函class{{a1=a2=}int{returnthis-}//一個函friendvoidsetA1(A1*p,inta1);inta1;intvoidsetA1(A1*p,int{p->a1=}void{A1setA1(&mya1,300);//通過函數修改A類的私有屬}6.2BABA強化訓static關鍵字強化訓練C++模擬商店貨物購進和賣出的情況。#include"iostream"usingnamespacestd;class{publicGoods( w){weight=w total_weight+=w;~Goods(){total_weight-=weight;} Weight(){return weight;}; TotalWeight(){return total_weight;}Goods*next; weight } Goods::total_weight=0//rvoidpurchase(Goods*&f,Goods*&r,intw{Goods*p=newGoods(w);p->next=NULL;if(f==NULL f=r=pelsernextp rrnext}voidsale(Goods*&f,Goods*&r{if(f==NULL){cout<<"Noanygoods!\n"; return;}Goods*q=f; f=f->next; deleteq;cout<<"saled.\n"}void{Goods*front=NULL,*rear=NULL; w; choice;{cout<<"Pleasechoice:\n"cout<<"Keyin1ispurchase,\nKeyin2issale,\nKeyin0isover.\n";cin>>choice;switchchoice //{case1 //11 cout<<"Inputweight:";cin>>w;purchase(front,rear,w) //從表入1個結break}case2 //21salefront,rear break //1case0 break //0}cout<<"Nowtotalweightis:"<<Goods::TotalWeight()<<endl}while(choice)}數組類封#include"iostream"#include"Array.h"usingnamespacestd;int#include"iostream"#include"Array.h"usingnamespacestd;int{Arrayfor(inti=0;i<a1.length();{a1.setData(i,}for(inti=0;i<a1.length();{printf("array%d:%d\n",i,}Arraya2=for(inti=0;i<a2.length();{printf("array%d:%d\n",i,}return0;}#ifndef_MYARRAY_H_class{intmLength;int*intlength();voidsetData(intindex,intvalue);intgetData(intindex);小classstruct類成員由private,protected,public決定特性。public成員集稱為接口 重載構造函數和構造函數提供了創建對象的不同初始化方式友員用關鍵字friend。友員是對類操作的一種輔助。一個類的友員可以訪運算符重概什么是運算符重已習慣于用加法運算符”+”5+85.8+3.67C++已經對運算符”+”int,float,doUble類型的運算。又如”<<“C++的位運算中的位移運算符(左移cout配合使用的流插入運算符,”>>“也是位移運算符(右移cin配合使用的流提取運算符。這就是運算符重載(operatoroverloading)。C++系統對”<<“和”>>“進stream中的。因此,如果要在程序中用”<<“和”>>”作流插入運算符和流提取運算stream(當然還應當包括”usingnamespacestd“)。++新的含義,使之一名多用。?運算符重載入門技術推plexc3=c1+//Complexclass{inta;intfriendComplexoperator+(Complex&c1,Complex&c2);Complex(inta=0,int{this->a=a;this->b=} {cout<<a<<"+"<<b<<"i}ComplexmyAdd(Complex&c1,Complex{Complextmp(c1.a+c2.a,c1.b+c2.b);returntmp;}Complexoperator+(Complex&c1,Complex{Complextmp(c1.a+c2.a,c1.b+return}void{Complexc1(1,2),c2(3,plexc3c1 //plexmyAdd(Complex&c1,Complex//1plexc3=myAdd(c1,//2operator+plexc3=operator+(c1,c2);//3Complexc3c1c2;//思考C++編譯器如何支持操作符重載機(根據類型){inta=0,b0,c;基礎類型C++編譯器知道如何加c=a}//4Complex//函數的應用場//friendComplexoperator+(Complex&c1,Complex return;}運算符重載的限運算符重載編程基例如//全局函數成+操作符Complexoperator+(Complex&c1,Complex//類成員函數成-操作符Complexoperator-(Complex運算符重載的兩種方//通過類成員函數完成-操作符重//函數Complexoperator-(Complex//函數調用分Complexc4=c1-c2;//c1.operator-//通過全局函數方法完成+操作符重//函數Complexoperator+(Complex&c1,Complexintmain(){Complexc1(1,2),c2(3,plexc31=operator+(c1,c2);Complexc3=c1+c2;}例如3:學員自己練習*//前置++{c1.a++;c1.breturn}//++c1需要寫出操作符重載函數////,operator++(Complex//分析函數返回值Complex&operator++(Complex&c1)//4.1前置—{return*this;}//4.2--//4.3前置—//5.1后置++Complexoperator++(Complex&c1,{Complextmp=c1;return}//5.2c1先使用后//5.3后置++Complexoperator++(Complex&c1int)++//6.1后置—{Complextmp=*this;return}//6.2c1//6.3后置--Complexoperator--(int)--C++中通過一個占位參數來區分前置運算和后置定義運算符重載函數名的步+()根據業務,完善函數返回值(看函數是返回還是指針元素),及實現函數業函數實現操作符重載的應用場1)函數和成員函數選擇方和->元函數操作istreamostreamC++cinistream的對象,coutostream<<ostream>>istream<<>><<ostream&operator<<(ostream&out,Complex{}//

out<<c1.a<<"+"<<c1.b<<"i"<<endl;returnout;//函數返回值充當左值需要返回一個<<//因拿到cout函數重載操作符使在第一個參數需要隱式轉換的情形下,使員函數重載運算符是正確的選 友員函數沒有this指針,所需操作數都必須在參數表顯式,很容易實現類型C++中不能員函數重載的運算符 4)函數案例vector#includeusingnamespace//vectorclass{publicvector(intsize=1)~vector()int&operator[](inti)friendostream&operator<<(ostream&output,vector&);friendistream&operator>>(istream&input,vector&);int*v;intlenvector::vector(intsize{if(size<=0||size>100{cout<<"Thesizeof"<<size<<"isnull!\n";abort()}v=newint[size] len=size}vector::{delete[]v;len=0;}int&vector::operator[](inti{if(i>=0&&i<len returnv[i]cout<<"Thesubscript"<<i<<"isoutside!\n" abort()}ostream&operator<<(ostream&output,vector&ary{for(inti=0;i<ary.len;i++)output<<ary[i]<<" ";output<<endl;returnoutput;}istream&operator>>(istream&input,vector&ary{for(inti=0;i<ary.len;i++)input>>ary[i]; input}void{intkcout<<"InputthelengthofvectorA:\n";cin>>k;vectorA(k)cout<<"InputtheelementsofvectorA:\n";cin>>A;cout<<"OutputtheelementsofvectorA:\n";cout<<A;}運算符重載提運算符重載機C++編譯器是如何支持操作符重載機制的重載賦值運算符賦值運算符重載用于對象數據的operator=類型 類名::operator=( 類名&)Name類,支持=結論返回一個3//obj3obj1;C++編譯器提供的號操作屬拷//obj4=obj3=Name&operator=(Name{//1先釋放obj3舊的內if(this->m_p!={delete[]m_p;m_len=0;}//2根據obj1分配內存大this->m_len=this->m_p=newcharstrcpy(m_p,obj1.m_p);return*this;}重載數組下表運算符[]()[]和()只能用成員函數重載,不能元函數重重載下標運算符[]運算符用于數據對象的元重載格 類型類:: (類型)xXx[yx.operator[](y重載函數調用()重載格 類型類:: (表達式表)xX的一個對象,則表達x(arg1,arg2,…可被解釋x.operator()(arg1,arg2,…//2:用重載()#include<iostream> {public operator( (doublex y)} F::operator( ( x y{return x*x+y*y;}voidmain(){ cout<<f(5.2,2.5)<<endl //f.operator()(5.2,}//例 用重載()運算符實現pk成員函#include<iostream.h> {public memFun(doublex y)} F::memFun( x y{return x*x+y*y;}voidmain(){ cout<<f.memFun(5.2,2.5)<<endl}為什么不要重載&&和||操作C++#include<cstdlib>#includeusingnamespacestd;classTest{inti;{this->i=}{ret.i=i+obj.i;returnret;}{returni&&obj.i;}&&void{inta1=0;inta2=if(a1&&(a1+a2)){}Testt1=0;Testt2=If(t1&&(t1+t2){ t1+ &&// }return;}運算符重載在項目開發中的應實現一個數組添加實現一個字符//C//C++//len0,MyStringa;“”MyStringa(“dddd”);MyStringb=a;b=“aaaaaa”b=a;if(a>if(a==b)b[i]=‘a’; //C//C++class{friendostream&operator<<(ostream&outconstMyString&s);public://構造和析構MyString(intlen=MyString(constcharMyString(constMyString&publicMyString&operator=(constcharMyString&operator=(constMyString&obj);char&operator[](intindex)const;booloperator==(constchar*p)const;booloperator!=(constchar*p)booloperator==(constMyString&s)const;booloperator!=(constMyString&s)public://stringtocchar*c_str();constchar*c_str()const;intlength(){return}intoperator<(constchar*p);intoperator>(constcharintoperator<(constMyString&s);intoperator>(constMyString char*m_p;智能指針類編12解決方案:例如:boostC3通過重載指針運算符*和->來模擬指針的行為==!=來模擬指針的比較class{{this->a=}void{}intclass{{p=}{this->p=}{delete}{return}{return}void{deletemyp->printT();//重載操作符->class{{p=}{this->p=}{delete}{return}int&{return}intvoid{int*p=newint(100);deletep;MyIntPointermyp=newint(200);8.7附錄:運算符和結C++operatorfriend關鍵字可以對函數或類開發權限和->++int3、繼承和派3.1繼承概要較好地進行面向對象程序設計,還必須了解面向對象程序設計另外兩個重要特征3.1.1類之間的關has-A,uses-Ais- 包含關系,用以描述一個類由多個“部件類”has-A關系用類成員表 3.1.2繼承關系舉兩個案例:1)植物繼承圖;2)3.1.3繼承相關概3.1.4派生類的定3.1.5繼承重要說12343.2派生類的控是這些成員的屬性,在派生過程中是可以調整的。3.2.1單個類的控2、思考:類成員的級別只有public和private是否足夠3.2.2不同的繼承方式會改變繼承成員的屬public繼承:父類成員在子類中保持原有級別privateprivate成員protectedpublicprotectedprivate能直接使用基類的私有成員。C++中子類對外屬性父類成員級式繼承中的控3.2.3“三看”原C++中的繼承方式(public、private、protected)會影響子類的對外屬性判斷某一句話,能否被3)看父類中的級別(public、private、protected)派生類類成員級別設置的原思考:如何恰當的使用public,protected和private為成員級別1、需要被外界的成員直接設置為public2、只能在當前類中的成員設置為privatepublicprivate綜合訓public繼承不會改變父類對外屬性private繼承會改變父類對外屬性為private;protected繼承會部分改變父類對外屬性。classB:publicA//類的繼承方式對子類對外屬性影#include<cstdlib>#includeusingnamespacestd;classA{inta;intb;int{a=b=c=}voidset(inta,intb,int{this->a=a;this->b=b;this->c=c;}classB:public{void{//cout<<"a="<<a;//errcout<<"b="<<b;cout<<"c="<<endl;}classC:protected{void{//cout<<"a="<<a;//errcout<<"b="<<b;cout<<"c="<<endl;}classD:private{void{//cout<<"a="<<a;//errcout<<"b="<<b<<endl;cout<<"c="<<c<<endl;}intmain_01(intargc,char{ABCDaa.c=100;//okbb.c=100;//cc.c100err//dd.c=100;aa.set(1,2,bb.set(10,20,//cc.set(40,50,60);//dd.set(70,80,90);return0;}3.3.1類型兼容性原父類可以直接子類對象(base*p#include<cstdlib>#includeusingnamespace父類可以直接子類對象classParent03{constchar*name;{name=}void{}classChild03:public{inti;Child03(int{this->name="Child2";this->i=i;}int{Child03//分別定義父類對象父類指針父類childParent03parent=child03;Parent03*pp=&child03;Parent03&rp=child03;return0;}C++編譯器的內部可以理解為結構體繼承中構造和析#include<cstdlib>#include<iostream>usingnamespacestd;class{Parent04(constchar*{}{}classChild04#include<cstdlib>#include<iostream>usingnamespacestd;class{Parent04(constchar*{}{}classChild04:public{Child04():Parent04("Parameterfrom{}{}void{Child04}intmain_04(intargc,char{return0;}3.3.3繼承中的構造析構調用原12343.3.4繼承與組合混搭情況下,構造和析構調用原 先析構自己,在析構成員變量、最后析構父#include<iostream>usingnamespaceclass{Object(constchar*{}{}classParent:public{Parent(constchar*s):{}{}classChild:public{ObjectObjectChild():o2("o2"),o1("o1"),Parent("Parameterfrom{}{}void{Child}intmain05(intargc,char{return0;}3.3.5繼承中的同名成員變量處理方124、同名成員在內存中的不同位3.3.6派生類中的static關鍵static關鍵字在一起會產生什么現象哪?根據靜態成員自身的特性和派生類的繼承方式,在類層次體系中具有不同的訪問性質(遵守派生類的控制) 派生類中靜態成員,用以下形式顯式說明類名::成或通過對象對象名.成1>static函數也遵守3個原2>static(不但要初始化,更重要的顯示的告訴編譯器分配內存3>3.4多繼3.4.1多繼承的應多繼承概 多繼承語 派生類名:控制基類名1 控制基類名2 …,控制基類名{ 類C可以根據控制同時繼承類A和類B的成員,并添加多繼承的派生類構執行順序與單繼承構造函數情況類似。多個直接基類構造函數執行順序取決于定義 一個派生類對象擁有多個直接或間接基類的成員不同名成員不會出現二義性。如果不同的基類有同名成員,派生類對象時應該加以識別。多繼承簡單3.4.2虛繼的名字進行時,可能產生二義性總結 的基類,則在對該基類中的名字進行時,可能產生 虛繼承使用關鍵 virtual3.5繼承總派生類對基類成員的由繼承方式和成員性質決定 C++提供虛繼承機制,防止類繼承關系中成員的二義性4、多多問題引如果子類定義了與父類中原型相同的函數會發生什么class{void{}classChild:public{void{}int{Childchild;Parent*p=NULL;p=&child;return0;}通過作用域分辨符::可以到父類中被隱藏的函數1p2print函數。//print//printf////1//3#includeusingnamespacestd;classParent{void{}classChild:public{void{}1p2print函數。{p-}void{ChildParent*pp=Parent&rp=////通過}int{ChildParent*p=NULL;p=&child;return0;}面向對象新需解決方C++virtual使用virtual的函數被重寫后即可展現多態特多態實案例場景HeroFighterAdvHeroFighterEnemyFighter戰斗. #include"iostream"usingnamespacestd;class{virtualint{return}classAdvHeroFighter:public{virtualint{return}class{int{return}//我的第3代代碼出現的時間晚于框架出現的時間////3C多態可以使用未來。80年了一個框架。90人寫的代碼{{printf("打敗敵人。勝利}{printf("。犧牲}}void{HeroFighterobjPK(&hf,&ef);AdvHeroFighter}多態工程意//3C多態可以使用未來。80年了一個框架。90人寫的代碼多態成立的條//3//1//2//3//1//2C//3要有父類指針(父類)指向子類對多態的理論基01靜態聯編和動態聯1binding3、動態聯編是指程序聯編推運行時進行,所以又稱為晚期聯編(遲綁定switchif41、C++C多態相關面試面試題1:請談談你對多態的理多態的實現有繼承、有virtual重寫、有父類指針()指向

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論