一、什麼是封裝:
將函數定義到結構體內部,就是封裝。
二、什麼是類:
帶有函數的結構體,稱爲類。
三、什麼是成員函數:
結構體裏面的函數,稱爲成員函數。c++
#include<stdio.h> #include<stdlib.h> #include<windows.h> struct Student { int a; int b; int c; int plus() { return a+b+c; } }; void main() { Student s = {1,2,3}; int r = s.plus(); //r=6 system("pause"); return ; }
一、什麼是this指針windows
一、this指針是編譯器默認傳入的,一般都會使用ecx進行參數的傳遞。
二、你用或者不用,它都在那。數組
三、this指針不能作++-等運算,不能從新被賦值。
四、this指針不佔用結構體的寬度。函數
二、this指針的使用this
struct sclass { int a; int b; void Init(int a,int b) { this->a=a; this->b= b; } void Print() { printf("%d %d" ,a,b); } };
一、構造函數設計
一、與類同名,沒有返回值
二、建立對象的時候執行,主要用於初始化
三、能夠有多個(最好有一個無參的),稱爲重載,其餘函數也能夠重載
四、編譯器不要求必須提供指針
二、析構函數總結:
一、只能有一個析構函數不能重載
二、不能帶任何參數
三、不能帶返回值
四、主要用於清理工做
五、編譯器不要求必須提供code
#include<stdio.h> #include<stdlib.h> #include<windows.h> struct Student { int a; int b; int c; Student() { printf("沒有參數的構造函數\n"); } Student(int a,int b,int c) { this->a = a; this->b = b; this->c = c; printf("有參數的構造函數\n"); } ~Student() { printf("析造函數\n"); } int plus() { return a+b+c; } }; void main() { Student s1; Student s2(1,2,3); system("pause"); return ; }
一、什麼是繼承?
繼承就是數據的複製
二、爲何要用繼承?
減小重複代碼的編寫對象
#include<stdio.h> #include<stdlib.h> #include<windows.h> struct X { int a; int b; }; struct Y:X { int c; int d; }; struct Z:Y { int e; int f; }; void main() { system("pause"); return ; }
一、咱們能夠在什麼地方建立對象?
<1>全局變量區
Person P;
<2>棧繼承
void Max() { Person p; }
<3>堆: new delete
在堆中建立對象:
Person* p= new Person();
釋放對象佔用的內存:
delete p;
#include<stdio.h> #include<stdlib.h> #include<windows.h> class Person { private: int x; int y; public: Person() { printf("Person()執行了\n"); } Person(int x,int y) { printf("Person(int x,int y)執行了\n"); this->x = x; this->y = y; } ~Person() { printf("~Person()執行了\n"); } }; void main() { Person* p = new Person(1,2); delete p; system("pause"); return ; }
二、new delete的本質:
<1>分析malloc函數的執行流程:
char* p= (char)malloc(128);
<2>分析new的執行流程:
Person p = new Person);
總結:
new = malloc +構造函數
一、引用就是變量的「別名」
<1>基本類型 intx= 1; int &p=x; p=2; //p就是x printf("%d \n",x); <2>類 Person p; Person &px=p; I px.x= 10; printf("%d \n",p.x); <3>指針 int******i= (int******)1; int******&r=i; r= (int******)2; printf("%d \n",r); <4>數組 int arr[]={1,2,3}; int (&px)[3] = arr; px[0]= 100; //px就是arr printf("%d \n",arr[0);
二、引用類型與指針的區別
一、引用必須賦初始值,且只能指向一個變量,「從-而終」。
二、對引用賦值,是對其指向的變量賦值,而並非修改引用自己的值。
三、對引用作運算,就是對其指向的變量作運算,而不是對引用自己作運算。
四、引用類型就是一個「弱化了的指針」。
#include<stdio.h> #include<stdlib.h> #include<windows.h> class Person { private: int Age; int Sex; public: //父類有參構造函數 Person(int Age,int Sex) { this->Age = Age; this->Sex = Sex; } void SetAge(int Age) { this->Age = Age; } void SetSex(int Sex) { this->Sex = Sex; } void print() { printf("%d %d\n",Age,Sex); } }; class Teacher:public Person { private: int Level; public: // :Person(Age,Sex)使用父類的有參構造函數 Teacher(int Age,int Sex,int Level):Person(Age,Sex) { this->Level = Level; } void SetLevel(int Level) { this->Level = Level; } }; void main() { Teacher t(1,2,3); t.print(); system("pause"); return ; }
一、純虛函數
<1>虛函數目的是提供-一個統一的接口,被繼承的子類重載,以多態的形式被調用。
<2>若是基類中的函數沒有任何實現的意義,那麼能夠定義成純虛函數:
virtual 返回類型 函數名(參數表)= 0;
<3>含有純虛函數的類被稱爲抽象類(abstract class),不能建立對象。
<4>虛函數能夠被直接使用,也能夠被子類(sub class)重載之後以多態的形式調用,而純虛函數必須在
子類(sub class)中實現該函數纔可使用。
二、什麼是多態?
多態就是可讓父類指針有多種形態。
C++中是經過虛函數實現的多態性。
#include<stdio.h> #include<stdlib.h> #include<windows.h> class Person { private: int Age; int Sex; public: Person(int Age,int Sex) { this->Age = Age; this->Sex = Sex; } void SetAge(int Age) { this->Age = Age; } void SetSex(int Sex) { this->Sex = Sex; } //虛函數 virtual void print() { printf("%d %d\n",Age,Sex); } }; class Teacher:public Person { private: int Level; public: Teacher(int Age,int Sex,int Level):Person(Age,Sex) { this->Level = Level; } void SetLevel(int Level) { this->Level = Level; } //重寫父類的print() void print() { Person::print(); printf("%d\n",Level); } }; //多態,參數是父類的引用 void MyPrint(Person& p) { p.print(); } void main() { Teacher t(1,2,3); MyPrint(t); system("pause"); return ; }
Number operator++(); Number operator--0; Number operator+(const Number& p); Number operator-(const Number& p); Number operator*(const Number& p); Number operator/(const Number& p); bool operator>(const Number& p); bool operator<(const Number& p); bool operator==(const Number& p);
#include<stdio.h> #include<stdlib.h> #include<windows.h> class Number { private: int x; int y; public: Number(int x,int y) { this->x = x; this->y = y; } //運算符重載 bool operator>(Number& n) { return this->x > n.x && this->y > n.y; } }; void main() { Number n1(1,2); Number n2(3,4); bool r = n1 > n2; system("pause"); return ; }
一、在函數中使用模版
函數模板的格式: template <class形參名,dlass 形參名,...>返回類型 函數名(參數列表) { 函數體 }
#include<stdio.h> #include<stdlib.h> #include<windows.h> template<class T> void Sort(T* arr ,int nLength) { int i; int k; for(i=0;i<nLength-1;i++) { for(k=0;k<nLength-1-i;k++) if(arr[k]> arr[k+1]) { T temp = arr[k]; arr[k] = arr[k+1]; arr[k+1] = temp; } } }; void main() { int arr[] = {1,3,2,5,4}; Sort(arr,5); system("pause"); return; }
二、在結構體/類中使用模版
類模板的格式爲:
template<class 形參名,class 形參名,...>class 類名 { }
#include<stdio.h> #include<stdlib.h> #include<windows.h> template<class T,class M> struct Base { T x; T y; M a; M b; int Max() { if(x>y) { return x; } else { return y; } } char Min() { if(a<b) { return a; } else { return b; } } }; void main() { Base<int,char> base; base.x =1; base.y =2; base.a=3; base.b=4; int r = base.Max(); system("pause"); return; }
一、若是不須要深拷貝,不要本身添加拷貝構造函數。
二、若是你添加了拷貝構造函數,那麼編譯器將不在提供,全部的事情都須要由新添加的函數本身來處理:
MyObject(const MyObject& obj) Base(obj) { printf(°拷貝構造函數執行了\n"); this->x= obj.x; this->y= obj.y; }
對象拷貝
#include<stdio.h> #include<stdlib.h> #include<windows.h> class CBase { private: int z; public: CBase(){} CBase(int Z) { this->z = z; } }; class CObfject:public CBase { private: int x; int y; public: CObfject(){} CObfject(int x,int y,int z):CBase(z) { this->x = x; this->y = y; } }; void main() { CObfject obj(1,2,3); CObfject objNew(obj); CObfject* p = new CObfject(obj); system("pause"); return; }
淺拷貝
#include<stdio.h> #include<stdlib.h> #include<windows.h> class CObject { private: int m_length; char* m_strBuffer; public: CObject(){} CObject(const char* str) { m_length = strlen(str) + 1; m_strBuffer = new char[m_length]; memset(m_strBuffer,0,m_length); strcpy(m_strBuffer,str); } ~CObject() { delete[] m_strBuffer; } }; void main() { CObject oldobj("derek"); CObject newobj(oldobj); //淺拷貝 system("pause"); return; }
深拷貝
#include<stdio.h> #include<stdlib.h> #include<windows.h> class CObject { private: int m_length; char* m_strBuffer; public: CObject(){} CObject(const char* str) { m_length = strlen(str) + 1; m_strBuffer = new char[m_length]; memset(m_strBuffer,0,m_length); strcpy(m_strBuffer,str); } //本身編寫的拷貝構造函數 CObject(const CObject& obj) { m_length = obj.m_length; m_strBuffer = new char[m_length]; memset(m_strBuffer,0,m_length); strcpy(m_strBuffer,obj.m_strBuffer); } ~CObject() { delete[] m_strBuffer; } }; void main() { CObject oldobj("derek"); CObject newobj(oldobj); //深拷貝 system("pause"); return; }
一、對象拷貝的兩種形式:
<1>使用拷貝構造函數
<2>使用「=」運算符
二、賦值運算符的問題
賦值運算符「=」與拷貝構造函數-同樣, 都是將成員的值直接複製,都是「淺拷貝」
三、重載賦值運算符:
<1>若是要重重載賦值運算符,必須對全部的屬性都要進行處理。
<2>若是有父類,要顯示調用父類的重載賦值運算符。
#include<stdio.h> #include<stdlib.h> #include<windows.h> class CBase { private: int m_nLength; char* m_pBuffer; public: CBase(){ m_nLength = 0; m_pBuffer = NULL; } CBase(char* szBuffer) { this->m_nLength = strlen(szBuffer)+1; m_pBuffer = new char[m_nLength]; strcpy(m_pBuffer,szBuffer); } CBase& operator=(const CBase& ref) { m_nLength = ref.m_nLength; if(m_pBuffer!=NULL) delete[] m_pBuffer; m_pBuffer = new char[m_nLength]; memcpy(m_pBuffer,ref.m_pBuffer,m_nLength); return *this; } virtual ~CBase(){ delete[] m_pBuffer; } }; void main() { CBase c1("china"),c2("derek"); c1 = c2; system("pause"); return; }
一、面向對象設計中的static之靜態數據成員:
<1>靜態數據成員存儲在全局數據區,且必須初始化,靜態數據成員初始化的格式爲:
<數據類型><類名> :<靜態數據成員名> =<值>
<2>靜態數據成員和普通數據成員同樣聽從public,protected,private訪問規則;
<3>類的靜態數據成員有兩種訪問形式:
<類對象名> <靜態數據成員名>
<類類型名> < 靜態數據成員名>
<4>同全局變量相比,使用靜態數據成員有兩個優點:
避免命名衝突;
能夠實現信息隱藏;
#include<stdio.h> #include<stdlib.h> #include<windows.h> class CBase { private: int x; int y; static int z; //私有的全局變量,CBase類的全部對象公用 public: void SetValue(int a) { z=a; } int GetValue() { return z; } }; //靜態成員的初始化 int CBase::z = 0; void main() { CBase c1,c2; c1.SetValue(10); int b = c2.GetValue(); printf("%d\n",b); //10 system("pause"); return; }
#include<stdio.h> #include<stdlib.h> #include<windows.h> class CBase { public: CBase(int x,int y); static int GetSum(); //靜態成員函數 private: int x,y; static int Sum; }; int CBase::Sum = 0; CBase::CBase(int x,int y) { this->x=x; this->y=y; } int CBase::GetSum() { return Sum; } void main() { CBase::GetSum(); system("pause"); return; }
二、單例模式
一個類只能建立一個對象
#include<stdio.h> #include<stdlib.h> #include<windows.h> class CSingleton { public: static CSingleton* GetInstance() { if(m_pInstance == NULL) m_pInstance = new CSingleton(); return m_pInstance; } private: CSingleton(){} static CSingleton* m_pInstance; //定義靜態成員 }; CSingleton* CSingleton::m_pInstance = NULL; //初始化靜態成員 void main() { //兩個實例指向的地址如出一轍 CSingleton* p1 = CSingleton::GetInstance(); CSingleton* p2 = CSingleton::GetInstance(); system("pause"); return; }