1. 程式人生 > >C++必備基礎知識和編程規範

C++必備基礎知識和編程規範

C++

C++必備基礎知識和編程規範


C語言是面向過程的程序設計,強調程序的執行順序,自上而下,而C++是面向對象的程序設計,將程序看做多個對象組成,每個對象有自己的屬性(變量)和行為(函數)。

2.屬性是描述對象特征的數據,行為是對象能進行的操作,如英雄聯盟裏每一個英雄都有自己的屬性(生命值,法力值,防禦力,攻擊力)和行為(普通攻擊,施放技能QWER)。


C++編程規範:

類名第一個單詞大寫,數據成員和變量小寫;

成員函數第二個單詞首字母大寫;

成員函數類外定義,類內聲明;

Set和構造函數的參數與數據同名,用this訪問;


一、什麽是類和對象


1.類(具有共性的實體)其實是C語言結構體的升級版,對象在程序中可以理解為編譯器為之分配了存儲空間的變量。

假如定義了一個帶函數的結構體,然後把struct 改成class

class Stu

{

int id;

char *name;

void study()

{

cout<<name<<"正在學習C++"<<endl;

}

};

在這裏class Stu就是類,用這個類定義一個變量Stu czy; czy就是對象

可以對對象進行操作如 czy.id =1;czy.study();

在C++中後綴為*.cpp,編譯器用g++,包含頭文件#include<iostream>

輸入輸出用cin,cout,需使用命名空間using namespace std;


2.命名空間用於解決命名重復問題,自定義作用域將多個變量和函數封裝起來,如:

namespace myName

{

int num = 10;

void fun()

{

std::cout<<"in mynamespace fun\n";

}

}

然後在main函數中引用, myName::fun();


3.I/O流 cin>> 和cout<< ,就是C語言中的printf()和scanf()但是不用指定格式,cin輸入數據類型不匹配時不讀取,多個輸入之間以空格分隔,遇到空格時結束,不檢查數據長度,有緩沖區溢出的危險。所以有了cin.getline(str, sizeof(str)),類似於c語言的fgets();


4.C++中結構名可以直接作為類型名(自動typedef),與C語言不同,c++中const修飾的值為常量,存在文字常量區。


5.缺省函數

帶有缺省參數的函數,如void fun(int num = 0);


6.重載函數

允許有同名的函數出現,但是參數不同,返回值不能作為區分的標誌,不能與缺省函數同名。


7.類型轉換

char a = char(num);

char *p = char *(num);


8.new/delete運算符

還記得C語言中的malloc和free吧,C語言中free釋放後,指針和空間都還在,但是指針已經沒有了對空間的操作權(好像還能讀取),所以應該使其指向NULL

new和delete不是函數是運算符

int num = 10;//棧區定義一個變量

如int *p = new int(100);//在堆區開辟了一塊4個字節的空間,裏面存了一個int型的數100

而char *str = new char[100];//在堆區開辟了一塊100個字節的空間,首地址賦給str

註意new int(100) 和new char[100]的區別(坑)。

new申請的空間自動賦值為0

刪除單個變量空間delete num;,刪除數組空間delete []str;


9.引用

操作符 &,代替指針,給變量取個別名,引用不占空間

int num = 10;

int &a = num;//定義一個num的別名a

引用必須賦初值,定義後不能修改。

可作為參數和返回值,提高程序的執行效率。


10.C++有封裝性,增加了對成員的訪問權限

private只能在類中訪問,public類中類外都能訪問,class類的成員默認為private

還是那個類

class Stu

{

private://這一行開始之後的所有成員都是私有成員

int id;

char *name;

public://這一行開始之後的所有成員都是公有成員

void study()

{

cout<<name<<"正在學習C++"<<endl;

}

};

規範1:C++中一般將屬性設置為private, 操作設置為public,然後每一個屬性都有相應的操作,如setId(),getId(), setName(), getName()好像面向對象編程都是這個套路

規範2:成員函數一般放在類外定義,類內聲明,定義時加 類名:: 指定

如void Stu::setId(int num)


11.構造函數

特殊的成員函數,用於在定義對象時進行初始化

構造函數名稱和類相同,可以有參也可以無參,沒有返回值(包括void),由編譯器自動調用。

如果沒有自定義構造函數則使用默認的構造函數(空函數),構造函數可重載,可缺省。

使用new定義對象時也會調用構造函數Stu *s2 = new Stu();


12.析構函數

構造函數的反操作,在刪除對象或對象退出生命周期時完成反初始化操作,如清理內存

在構造函數前加~號,一般情況下析構函數由編譯器執行,使用delete時會觸發調用

一般情況下不需要定義析構函數(沒有為類中的成員開辟堆區內存)

如在構造函數中有

Stu()

{

name = new char[100];

}

則必須用析構函數

~Stu()

{

if(NULL != name)

{

delete []name;

name = NULL;

}

}

每個類只有一個析構函數,不能重載也不能有參數


13.拷貝構造函數

特殊的構造函數,定義對象時使用已存在對象完成初始化

名稱與類相同,無返回值,參數必須是當前類的對象的引用


使用條件:寫Stu s2 = s1;和Stu s3(s1);時會調用拷貝構造函數,而寫Stu s2 ; s2 = s1;則不會調用拷貝構造函數。

一般情況下不需要自定義拷貝構造函數(和析構函數一樣沒有為類中的成員開辟堆區內存),因為如果不定義拷貝函數編譯器只會進行淺拷貝操作(只拷貝值,不拷貝內存空間),釋放時會出現段錯誤

所以當類中有指針且為指針分配了空間時,要自定義拷貝構造函數進行深拷貝。

Stu(const Stu &s1)

{

id = s1.id;

name = new char[strlen(s1.name)+1];

strcpy(name, s1.name);

}

類中有動態內存分配時,需要自定義拷貝構造函數,否則會因為多次釋放同一段內存導致段錯誤(double free or corruption)


14.const 修飾的成員函數

void setId(int num)const

{

}

稱為只讀成員函數,只能讀取成員值,不能修改(除非是mutable int id)


15.對象數組:有限個相同類型的對象構成的集合

Stu array[3]={Stu(1), Stu(2)};


16.this指針

一個隱藏的指針變量,是成員函數的第一個參數,類型為對象的類型

如果對象的成員函數形參和屬性相同,可用this指定

用於規範:

void setId(int id)

{

this->id = id;

}

如果要重復調用成員如:s1.setId(10).getId();可使setId()返回對象的引用(return *this)


17.枚舉(常與switch使用)

構造函數列表

Stu():id(10), score(99.5)

{


}

使用方法和構造函數相同,但是可以完成特殊成員的初始化如const修飾的成員


18.const修飾的成員

只能用構造函數列表初始化,const修飾的成員在不同的對象中可以有不同的值


19.靜態成員 static int num; static int getNum();

靜態數據成員和靜態成員函數,初始為0

靜態數據成員在類外定義,類內聲明,和類的其它成員不在一塊內存,不占用對象的空間,sizeof()不會計算。

屬於整個類而不是某個對象,可通過類名::對象訪問Stu::num

作用之一:代替全局變量

靜態成員函數不能使用非靜態數據成員,只能訪問靜態數據成員和全局變量, 不能使用this

為了更好地操作使用靜態數據成員而出現靜態成員函數,在定義對象之前即可操作靜態數據成員。


20.對象成員

即類的嵌套,類似結構體嵌套,一個類的對象作為另一個類的成員

給對象成員中的數據成員賦值要用構造函數列表

class A

{

public:

int aNum;

A(){

aNum = 1;

cout<<"在A構造函數中"<<endl;

}

A(int num){

aNum = num;

}

};

class B

{

public:

int bNum;

A a;

B()

{

bNum = 2;

cout<<"在B構造函數中"<<endl;

}

B(int num):a(10)

{

bNum = num;

}

};


21.友元

在類外訪問類的私有成員

友元函數,友元成員,友元類

關鍵字friend

友元函數:將一個類外函數聲明為friend,可以訪問類的私有成員,友元函數定義有順序要求

友元成員:一個類的成員函數聲明為friend如:friend void Tch::getNum(),另一個類的成員函數可以訪問該類成員。

友元類:friend class Tch;

友元一般不使用,因為破壞了函數的封裝性


22.運算符重載

也叫運算符重載函數,為適應對象操作

int operator +(A a1, A a2)

{

return a1.num+a2.num;

}

運算符重載實質為函數重載,必須遵循其原則

除了成員運算符".", "sizeof", 條件運算符"?:", 作用域運算符"::"之外都可以重載,重載後優先級和結合性不變

一般重載為友元函數或成員函數

單目運算符重載為成員函數,雙目運算符重載為友元函數

"=", "()", "[]", "->"不能重載為友元





C++必備基礎知識和編程規範