溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

C++的數(shù)據(jù)共享與保護(hù)實(shí)例分析

發(fā)布時(shí)間:2022-03-14 09:07:50 來源:億速云 閱讀:120 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要講解了“C++的數(shù)據(jù)共享與保護(hù)實(shí)例分析”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“C++的數(shù)據(jù)共享與保護(hù)實(shí)例分析”吧!

    1.作用域

    作用域是一個(gè)標(biāo)識(shí)符在程序正文中有效的區(qū)域

    作用域關(guān)系從大到小為:

    命名空間作用域 > 類作用域 > 局部作用域

    標(biāo)識(shí)符的有效范圍就是標(biāo)識(shí)符的可見性,可見性的一般規(guī)則為:

    • 標(biāo)識(shí)符聲明在前,使用在后

    • 在同一作用域中,不能聲明同名的標(biāo)識(shí)符

    • 在沒有包含關(guān)系的不同的作用域中聲明的同名標(biāo)識(shí)符,互不影響

    • 如果在多個(gè)作用域中定義了同名標(biāo)識(shí)符,則外層標(biāo)識(shí)符在內(nèi)層不可見

    2.對(duì)象生存期

    如果對(duì)象生存期與程序的運(yùn)行期相同,則它具有靜態(tài)生存期

    局部生存期對(duì)象誕生于聲明點(diǎn),結(jié)束于聲明所在塊執(zhí)行完畢之時(shí)

    • 命名空間作用域中聲明的對(duì)象都具有靜態(tài)生存期

    • 定義時(shí)未指定初值的基本類型靜態(tài)生存期變量,會(huì)被賦予0值初始化

    • 如果要在函數(shù)內(nèi)部的局部作用域中聲明具有靜態(tài)生存期的對(duì)象,則要使用關(guān)鍵字static

    void f()
    {
    	static int m=0;	//m僅在f中能訪問 
    	m++;
    	cout<<m<<endl;
    }

    靜態(tài)數(shù)據(jù)成員

    如果某個(gè)屬性為整個(gè)類所共有,可以采用static關(guān)鍵字來聲明為靜態(tài)成員。

    • 靜態(tài)成員在每個(gè)類中只有一個(gè)副本,由該類的所有對(duì)象共同維護(hù)和使用

    • 在類中不能對(duì)static靜態(tài)數(shù)據(jù)成員進(jìn)行初始化,要初始化必須在類外進(jìn)行定義

    class A{
    public:
    	static int m; 
    };
    int A::m=20;			//在類外進(jìn)行初始化 
    int main(){
    	A a,b;
    	a.m=10;			    //可以賦值 
    	cout<<a.m<<endl;
    	cout<<b.m<<endl;	//兩者的值相同
    }

    靜態(tài)成員函數(shù)

    • 靜態(tài)成員函數(shù)可以通過類名或?qū)ο竺麃磉M(jìn)行調(diào)用,非靜態(tài)成員函數(shù)只能通過對(duì)象名來調(diào)用

    • 靜態(tài)成員函數(shù)可以直接訪問該類的靜態(tài)數(shù)據(jù)和函數(shù)成員,而訪問非靜態(tài)成員,必須通過對(duì)象名

    class A{
    public:
    	static void f(A a);
    	static void g(){
    		cout<<"hello"<<endl;
    	}
    	void fun(){
    		cout<<"world"<<endl;
    	}
    private:
    	int x;
    	static int y;
    };
    int A::y=10;
    void A::f(A a){
    	cout<<a.x<<endl;    //必須通過對(duì)象名訪問
    	cout<<y<<endl; 		//直接訪問該類的靜態(tài)數(shù)據(jù)成員 
    	g();				//直接訪問該類的靜態(tài)成員函數(shù) 
    }
    int main(){
    	A a;
    	A::f(a);            //直接通過類名調(diào)用
    	return 0; 
    }

    3.類的友元

    友元關(guān)系是一種數(shù)據(jù)共享機(jī)制,通過友元關(guān)系,一個(gè)普通函數(shù)或者類中的成員函數(shù)可以訪問封裝于另外一個(gè)類中的數(shù)據(jù)

    為了確保數(shù)據(jù)的完整性和封閉性,建議盡量少地使用友元

    友元函數(shù)

    友元函數(shù)是類中用關(guān)鍵字friend修飾的非成員函數(shù),在它的函數(shù)體中可以通過對(duì)象名訪問類的private和protected成員

    class A{
    public:
    	friend int main();
    private:
    	int x;
    };
    int main(){
    	A a;
    	a.x=5;	//訪問 private對(duì)象 
    }

    友元類

    若B類為A類的友元類,則B類的所有成員函數(shù)都是A類的友元函數(shù),都可以訪問A類的private和protected成員

    class A{
    public:
    	friend class B;
    private:
    	int x,y;
    	void f(){
    		cout<<x<<endl;
    	} 
    };
    class B{
    public:
    	void print(){
    		a.x=5;
    		a.y=10;
    		cout<<a.y<<endl;//可以訪問A類對(duì)象的私有成員 
    		a.f();			//可以訪問A類對(duì)象的私有函數(shù) 
    	}
    private:
    	A a;
    };

    注意(!?。。?/p>

    1.友元關(guān)系是單向的。

    B類是A類的友元,B能訪問A的私有數(shù)據(jù),但A不能訪問B的私有數(shù)據(jù)

    2.友元關(guān)系不能傳遞。B是A的友元,C是B的友元,C和A之間如果沒有聲明就不存在友元關(guān)系

    3.友元關(guān)系不能被繼承。 

    4.共享數(shù)據(jù)的保護(hù)

    常對(duì)象

    數(shù)據(jù)成員值在對(duì)象的整個(gè)生存期間不能被修改的對(duì)象叫做常對(duì)象,一般用const進(jìn)行修飾

    常對(duì)象必須進(jìn)行初始化,而且不能被更新

    聲明常對(duì)象的語法形式為:

    const 類型說明符 對(duì)象名;

    class A{
    public:
    	A(int i,int j):x(i),y(j){···}
    private:
    	int x,y;
    };
    int main(){
    	const A a(3,4); //a為常對(duì)象,不能被更新 
    }

    常成員函數(shù)

    使用const關(guān)鍵字修飾的函數(shù)為常成員函數(shù)

    語法:

    類型說明符 函數(shù)名(參數(shù)表)const;

    如果將一個(gè)對(duì)象說明為常對(duì)象,通過該常對(duì)象只能調(diào)用它的常成員函數(shù),不能調(diào)用其他函數(shù)(常對(duì)象唯一的對(duì)外接口方式)

    class A{
    public:
    	A(int i,int j):x(i),y(j){···}
    	void print(){
    		cout<<x<<" "<<y<<endl;
    	}
    	void print() const{
    		//常成員函數(shù)
    		cout<<x<<" const "<<y<<endl;
    	}
    private:
    	int x,y;
    };
    int main(){
    	A a(1,2);
    	a.print();  //調(diào)用 void print() 
    	const A b(3,4);
    	b.print();  //調(diào)用 void print() const 
    }

    使用const說明的數(shù)據(jù)成員為常數(shù)據(jù)成員

    類中說明了常數(shù)據(jù)成員,任何函數(shù)不能對(duì)它賦值,構(gòu)造函數(shù)對(duì)它進(jìn)行初始化只能通過初始化列表

    class A{
    public:	
    	//常數(shù)據(jù)成員只能通過構(gòu)造函數(shù)的初始化列表來獲得初值 
    	A(int i):a(i){···}
    private:
    	const int a;       //常數(shù)據(jù)成員
    	static const int b;//靜態(tài)常數(shù)據(jù)成員
    };
    const int A::b=10;  //靜態(tài)常數(shù)據(jù)成員在類外初始化

    常引用

    如果在聲明引用時(shí)用const修飾,被聲明的引用就是常引用,常引用所引用的對(duì)象不能被更新

    常引用的聲明形式:

    const 類型說明符 & 引用名;

    一個(gè)常引用,無論是綁定到一個(gè)普通對(duì)象,還是一個(gè)常對(duì)象,通過該引用訪問該對(duì)象時(shí),都只能把該對(duì)象當(dāng)做常對(duì)象

    class Point{
    public:
    	Point(int x,int y):x(x),y(y){}
    	friend float dist(const Point &p1,const Point &p2);
    private:
    	int x,y;
    };
    float dist(const Point &p1,const Point &p2){   //常引用作形參
    	double x=p1.x-p2.x;
    	double y=p1.y-p2.y;
    	return sqrt(x*x+y*y);
    }
    int main(){
    	const Point m1(1,1),m2(4,5);
    	cout<<dist(m1,m2)<<endl;    //兩點(diǎn)間距離 
    }

    Tips

    • include書寫方式

      • include <文件名>,按照標(biāo)準(zhǔn)方式搜索嵌入文件,文件位于編譯環(huán)境include子目錄下。示例:include <iostream>

      • include “文件名”,在當(dāng)前目錄下搜索嵌入文件,如果搜不到則轉(zhuǎn)為標(biāo)準(zhǔn)搜索。示例:include "point.h"

    • 外部變量

      • 如果一個(gè)變量可以在本文件和其他文件中使用,稱為外部變量,用 extern 關(guān)鍵字說明

    extern int n;//聲明一個(gè)在其他文件定義的外部變量n

    對(duì)于外部函數(shù),加不加 extern 效果都是一樣的

    如果在定義變量和函數(shù)時(shí)使用static關(guān)鍵字,可以讓該變量和函數(shù)無法被其他編譯單元引用

    • 動(dòng)態(tài)內(nèi)存分配

    運(yùn)算符new的功能是動(dòng)態(tài)分配內(nèi)存,語法形式為

    new 數(shù)據(jù)類型(初始化參數(shù)列表)

    對(duì)于基本數(shù)據(jù)類型,如果不希望在分配內(nèi)存后設(shè)立初值,可以把括號(hào)省去

    int* point = new int;

    如果保留括號(hào),但括號(hào)中不寫任何數(shù)值,則表示用0來進(jìn)行初始化

    int* point = new int( );

    運(yùn)算符delete用來刪除由new建立的對(duì)象,釋放指針?biāo)赶虻膬?nèi)存空間,格式為:

    delete 指針名;

    用new分配的內(nèi)存,必須用delete加以釋放,否則會(huì)造成“內(nèi)存泄漏”,而且只用delete進(jìn)行一次刪除,對(duì)同一內(nèi)存空間多次使用delete進(jìn)行刪除會(huì)導(dǎo)致運(yùn)行錯(cuò)誤

    用new創(chuàng)建一維數(shù)組時(shí),在方括號(hào)后加或者不加小括號(hào)的區(qū)別和“new T( )”一樣,用delete刪除時(shí)在指針名前面要加“[ ]”

    int* p = new int[100]; //不設(shè)置初值
    int *p = new int[100] ( ); //用0進(jìn)行初始化
    delete[ ] p;

    • 深復(fù)制與淺復(fù)制

      • 淺復(fù)制只是對(duì)指針的復(fù)制,復(fù)制后兩個(gè)指針指向同一個(gè)內(nèi)存空間;

      • 深復(fù)制不但對(duì)指針進(jìn)行復(fù)制,而且對(duì)指針指向的內(nèi)容進(jìn)行復(fù)制,經(jīng)深復(fù)制后的指針是指向兩個(gè)不同地址的指針

    默認(rèn)復(fù)制構(gòu)造函數(shù),進(jìn)行的是淺復(fù)制,對(duì)指針復(fù)制后會(huì)出現(xiàn)兩個(gè)指針指向同一個(gè)內(nèi)存空間的情況,內(nèi)存空間會(huì)被析構(gòu)函數(shù)釋放兩次,導(dǎo)致運(yùn)行錯(cuò)誤

    解決這一問題必須要自己定義復(fù)制構(gòu)造函數(shù),使復(fù)制后的對(duì)象指針成員有自己的內(nèi)存空間,即進(jìn)行深復(fù)制,這樣就避免了內(nèi)存泄漏發(fā)生。

    • this指針

      • this指針是一個(gè)隱含于每一個(gè)類的非靜態(tài)成員函數(shù)中的特殊指針,它用于指向正在被成員函數(shù)操作的對(duì)象

      • 當(dāng)局部作用域中聲明了與類成員同名的標(biāo)識(shí)符時(shí),對(duì)該標(biāo)識(shí)符的直接引用代表的是局部作用域中所聲明的標(biāo)識(shí)符,這時(shí)為了訪問該類成員,可以通過this指針

    class A{
    public:
    	void display(int x){
    		this->x=x;   //前一個(gè)x為數(shù)據(jù)成員,后一個(gè)x為形參
    	}
    private: 
    	int x;
    };

    感謝各位的閱讀,以上就是“C++的數(shù)據(jù)共享與保護(hù)實(shí)例分析”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對(duì)C++的數(shù)據(jù)共享與保護(hù)實(shí)例分析這一問題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    c++
    AI