C與C++的不同點
- C++在struct,union中定義的函數叫成員函數,在class中定義的數據叫數據成員
- C++引入了三個存取權限的關鍵字:public,protected,private
public:表示數據成員或成員函數是公有的
protected:表示數據是受保護的。不允許其他的程序對其進行直接存取,只能通過他所在的成員函數進行存取
private:表示數據是私有的。與protected一樣
成員訪問控制 public protected private 類自身 yes yes yes 派生類 yes yes no 其他類 yes no no
注意:private與protected的區別:private的數據是不可被繼承的;protected的數據是可以被繼承的基類成員訪問控制 繼承訪問控制 在派生類中的訪問控制 publilc public public protected protected private 不可訪問 publilc protected protected protected protected private 不可訪問 publilc private private protected private private 不可訪問 - C++中可以把結構體名當做數據類型來使用
struct Student{char name[20];} Student stu;//定義Student類型的變量
- struct關鍵字定義的數據成員或數據函數缺省時是public;class關鍵字定義的數據成員或成員函數缺省是private。用union定義的類其所有的成員都是public,這種安排是不可以改變的,它不能使用存取限定符來進行修飾數據權限
- C++中定義參數可以帶缺省參數。帶缺省參數的函數調用時,如果缺省參數中沒有給值,則將缺省值賦值給參數變量
//定義了缺省參數的函數 int fun(int x,int y,int z = 100);
注意:帶有缺省值的參數必須放在參數列表的尾部
作用域限定符
代碼:
View Code

C++繼承
概念:如果B類是由A類繼承而來的,那么把B類叫作派生類,A類叫作基類
單繼承
單繼承語法:
class 派生類名 : 繼承方式{ //定義類實體 }
#include<iostream> using namespace std; //基類 class A{ private: int x; int y; public: void setX(int x){ this->x = x; } void setY(int y){ this->y = y; } int getX(){ return x; } int getY(){ return y; } }; //派生類 class B:public A{ private: int z; public: void setZ(int z){ this->z = z; } int getZ(){ return z; } }; int main(){ B b; b.setX(100); b.setY(200); b.setZ(300); cout << b.getX() << "\n"; cout << b.getY() << "\n"; cout << b.getZ() << "\n"; }
示例圖:

多繼承
多繼承語法:
class 派生類名 : 繼承方式1 基類名1,繼承方式2 基類名2,...{ //定義類實體 };
#include<iostream> using namespace std; //基類1 class A{ protected: int x; public: void setX(int x){ this->x = x; } int getX(){ return x; } }; //基類2 class B{ protected: int y; public: int getY(){ return y; } void setY(int y){ this->y = y; } }; //派生類 class C:public A,public B{ protected: int z; public: void setZ(int z){ this->z = z; } int getZ(){ return z; } }; int main(){ C c; c.setX(100); c.setY(200); c.setZ(300); cout << c.getX() << "\n"; cout << c.getY() << "\n"; cout << c.getZ() << "\n"; }
示例圖:

C++重載
重載運算符
概念:對已有的運算符進行重新定義其功能
| 可重載運算符 | 不可重載運算符 |
| 雙目運算符(+,-,*,/,%) | .(成員訪問運算符) |
| 關系運算符(==,!=,>,<,>=,<=) | .* , ->*(成員指針訪問運算符) |
| 邏輯運算符(||,&&,!) | ::(域運算符) |
| 單目運算符(+(正),-(負),*,&) | sizeof |
| 自增(++),自減(--) | ?: |
| 位運算符(|,&,~,^,<<,>>) | #(預處理符號) |
| 賦值運算符(=,+=,-=,*=,/=,&=,|=,...) | |
| 空間申請與釋放(new,delete,new[],delete[]) | |
| 其他運算符(()(函數調用),->(成員訪問),,(逗號),[](下標)) |
#include <iostream> using namespace std; class Box{ private: int width; int height; public: Box(){ width = 0; height = 0; } Box(int width,int height){ this->width = width; this->height = height; } //重載 + 運算符 Box operator + (const Box &b){ Box box; box.width = this->width + b.width; box.height = this->height + b.height; return box; } //重載輸出流 friend ostream &operator<<( ostream &os,const Box &b ){ os << "width:" << b.width << " height:" << b.height << "\n"; return os; } //重載輸入流 friend istream &operator>>(istream &is,Box &b){ is >> b.width >> b.height; return is; } }; int main(){ Box b1(100,200),b2(300,200); Box b3 = b1+b2; //cin >> b3; cout << b3 << endl; return 0; }
示例圖:
重載函數
概念:在一個類中定義多個相同名字的函數,但是參數列表或參數個數不相同的方法
#include <iostream> #include <cstdio> using namespace std; class A{ public: void print(int x){ printf("x=%d\n",x); } void print(int x,int y){ printf("x=%d,y=%d\n",x,y); } void print(double z){ printf("z=%lf\n",z); } }; int main(){ A a; a.print(100); a.print(200,300); a.print(666.6); return 0; }
示例圖:

C++成員函數
成員函數的實現:在類定義的內部或外部實現函數。前者稱為內聯成員函數,后者稱為外部成員函數
內部實現:
class A{ private: int x; int y; public:
//定義內聯函數 int getX(){return x;} int getY(){return y;} }
外部實現:
class B{ protected: int x; public: void setX(int x); int getX(); } //外部實現 void B::setX(int x){ this->x = x; } int B::getX(){ return this->x; }
C++構造函數與析構函數
概念:構造函數是在建立對象時被調用的;析構函數是在刪除對象前被調用的
內部定義:
#include<iostream> using namespace std; class Person{ protected: string name; public: //定義無參構造函數 Person(){ cout << "Person is being created\n"; name = "Lam"; } //定義有參構造函數 Person(string name){ cout << "Person is being created\n"; this->name = name; } //定義析構函數 ~Person(){ cout << "Person is being deleted\n"; } }; int main(){ Person p;//調用無參構造函數 cout << "Next1\n"; Person p2("Lam");//調用有參構造函數 cout << "Next2\n"; }
外部定義:
#include<iostream> using namespace std; class Person{ protected: string name; public: //定義無參構造函數 Person(); //定義有參構造函數 Person(string name); //定義析構函數 ~Person(); }; Person::Person(){ cout << "Person is being created\n"; name = "Lam"; } Person::Person(string name){ cout << "Person is being created\n"; this->name = name; } Person::~Person(){ cout << "Person is being deleted\n"; } int main(){ Person p;//調用無參構造函數 cout << "Next1\n"; Person p2("Lam");//調用有參構造函數 cout << "Next2\n"; }
示例圖:

調用基(父)類函數
問題:如果想在派生類中使用基類中的函數(這里的函數是指與派生類的函數名相同,但是是功能不同的函數)我們該怎么做呢??
代碼:
#include <iostream> using namespace std; /** 派生類類型變量.基類類名::引用的函數(); */ class A{ public: A(){ cout<<"execution function A()\n"; } void print(){ cout << "print A\n"; } }; class B:public A{ public: B(){ cout << "execution function B()\n"; } void print(){ cout << "print B\n"; } }; int main(){ B b; b.print();//print B ((A)b).print();//print A b.A::print();//print A return 0; }
示例圖:

派生類的構造函數實現及執行過程
代碼:
#include <iostream> using namespace std; class A{ public: int x; public: A(){ cout<<"execution function A()\n"; x = 1; } A(int x){ //不會調用無參構造方法A() this->x = x; cout << "x:" << x << endl; } }; class B:public A{ public: int y; public: B(){ //隱式調用父類無參構造函數A() cout << "execution function B()\n"; y = 1; } B(int x,int y):A(x){//派生類構造函數實現 //這里因為調用了A(x)構造函數,所以不會在隱式調用父類無參構造函數A() this->y = y; cout << "y:" << y << endl; } }; int main(){ cout << "=========A()============\n"; A a(200); cout << a.x << endl; cout << "=========B()============\n"; B b1; cout << b1.x << endl; cout << b1.y << endl; cout << "=========B(int x,int y)========\n"; B b2(100,200);//首先調用B類中的有參構造方法B(int y),然后有參構造方法中隱式調用父類無參構造方法 cout << b2.x << endl; cout << b2.y << endl; return 0; }
示例圖:

C++構造函數、析構函數與普通函數的區別
- 構造函數的名字必須與類名相同;析構函數的名字是以波浪號(~)開頭加類名組成的。
- 當建立對象時或復制對象時,構造函數會被自動調用;當刪除對象前,析構函數會被自動調用。
- 構造函數與構造函數都無返回值。
- 構造函數與析構函數都無法被繼承,但是派生類可以調用基類的構造函數
- 構造函數允許重載,有自己的默認參數和初始化列表
- 構造函數不可以是虛函數;析構函數可以是虛函數
- 析構函數不接受任何參數,沒有返回值,沒有任何值要說明
C++動態對象
概念:在C++ 中提供了動態申請和釋放內存空間的兩個關鍵字,分別是new(申請),delete(釋放)。
語法:
new 數據類型; delete 指針變量;
注意:new申請內存地址空間成功時,返回對象的指針;若申請失敗,則返回空指針(NULL)
代碼:
#include <iostream> #define N 100 #define row 4 #define col 6 using namespace std; class A{ public: A(){ cout << "execution function A()" << endl; } ~A(){ cout << "execution function ~A()" << endl; } }; int main(){ //new的使用 //1.基本類型的動態內存分配 double *p = new double; *p = 10000.999; //2.數組的動態內存分配(一維數組) char *c = new char[N]; //3.數組的動態內存分配(4*6的二維數組) int **b = new int*[row]; for(int i = 0; i < N; i++){ b[i] = new int[col]; } //4.對象的動態內存分配 A *a = new A(); A *arr = new A[N]; //delete的使用 //1.釋放指針p的內存 delete p; //2.釋放指針ch所指向的數組 delete [] c; //3.釋放二級指針b所指向的數組 for(int i = 0; i < 4; i++){ delete [] b[i]; } delete[] b; return 0; }

