C++ 學習總結(十)——C++類與對象,及構造函數,析構函數,拷貝構造函數

一.C++類與對象

1.基本單位是類。

2.類是數據和操作數據的函數的封裝。

3.對象使用自己的方法完成對數據的操作。

4.類可以隱藏數據和操作細節,對象通過類結構與外部通信。

C++與C進行代碼重用是通過類和函數來實現的。C++同時可以通過類來限定數據訪問得的權限。

C++通過類的繼承實現代碼重用,類的封裝實現權限封裝,數據與代碼合爲一體。類的多態實現一個接口的多個功能。通過接口封裝實現不同的權限。

類中包含三種類型的數據: private 私有數據類型     protected 保護類型       private 私有類型  

1>三種類型的訪問權限:

private protected public
私有數據類型盡在類中可見 在該類和派生類中可見 提供外部的接口,外部可訪問的數據及方法
2>class struct union三種類型的默認類型:

class struct union
默認下爲私有數據類型和方法 默認情況下爲公有public 默認情況下爲公有public
二.類與對象的定義

1.允許已定義的類名出現在累的說明中。

2.類可以無名,用於直接申明對象。

3.類是一個程序包,可以只有數據成員或函數,或者爲空,空類的對象大小不爲零,空類佔一個字節,表明類存在。空類中函數在代碼區,不包括函數,大小佔一個字節。

#include<iostream>
class kong 
{
public:
   //int num;
	void go(int num)
	{
		std::cout << "12345" << std::endl;
	}
};
void main()
{
	kong kong1;
	//kong1.num = 100;
	//std::cout << sizeof(kong) << std::endl; 空類佔用一個字節,表明類存在,代碼不計入sizeof
	std::cout << sizeof(kong) << std::endl;
	std::cout << &kong1<< std::endl;
	std::cin.get();
}
4.類中包含常量數據以及常量函數的情況

class myclass1
{
 public:
int a;
const int b=0;//常量必須進行初始化
mutable int e;//不被const限制.
//限定不對成員變量賦值,但是可以對mutable數據賦值,
void set(int a) const
{
}
};
三.構造函數與析構函數

作用:分配空間,爲對象成員賦值,請求其他資源

1.所有類都默認有一個構造函數,一個析構函數和拷貝構造函數。

2.構造函數和析構函數都可以重載,且沒有返回值。

#include<iostream>
class myclass
{
public:
	int num;
public:
	//構造函數與析構函數的重載
	myclass():num(4) //變量初始化方式二
	{
		//num = 4;變量 初始化方式1,
		std::cout << "對象被建立"<<std::endl;
	}
	myclass(int a)	//構造函數的重載
	{
		this->num = a;
	}
	~myclass()
	{
		std::cout << "對象被銷燬"<<std::endl;
	}
};
void run()
{
	myclass classa,classb(8);//等價於classb=10;
	std::cout << classa.num << " " << classb.num << std::endl;

}
void main1()
{
	myclass *p = new myclass(10);  //等價於*p=(new myclass(10))
	p = new myclass(100);
	run();
	


	int num = 4;
	int data(4);//調用int類型的構造函數

	std::cin.get();
}
3.類中包含其他類時,所包含的類首先創建,然後該類創建。銷燬時,該類先銷燬,所包含的類後銷燬。
#include<iostream>
//系統自動生成
class fushu
{
public:
	fushu();
	~fushu();

};

fushu::fushu()
{
	std::cout << "fushu類的構造" << std::endl;
}
fushu::~fushu()
{
	std::cout << "fushu類的銷燬" << std::endl;
}
class math
{
public:
	fushu fushu1;
	math()
	{
		std::cout << "math類的構造" << std::endl;
	}
	~math()
	{
		std::cout << "math類的銷燬" << std::endl;
	}
};
void go()
{
	math math1;
}
void main2()
{
	go();//類創建過程:fushu類先創建,math類創建,	類銷燬過程:math先銷燬,然後fushu銷燬
	std::cin.get();
}
4.explicit 顯式調用,不允許進行隱式類型轉換。

#include<iostream>
#include<array>
#include<vector>
class classobj
{
public:
	int num;
public:
	explicit classobj(int data)
	{
		this->num = data;
		std::cout << "類的創建以及數據初始化"<<num << std::endl;
	}
	~classobj()
	{
		std::cout << "被銷燬" << num << std::endl;
	}
protected:
private:
};
void main()
{
	//classobj num = 5;//賦值號,類型轉換
	classobj data(5);//	創建對象必須選擇合適的構造函數
	//classobj class1[10];
	//classobj *p = new classobj;
	//classobj *p = new classobj(5); 
	//classobj *p = new classobj(5);
	classobj obj(5);
	std::array<classobj, 2> arg = {data,obj};
	std::vector<classobj> arg1;
	arg1.push_back(obj);
	std::cin.get();
}
5.拷貝構造函數

1>類會默認生成,可以通過delete與default刪除和生成默認的構造函數和拷貝構造函數。禁用拷貝構造函數,禁止別人拷貝數據。同時類還重載了“=”賦值運算符。

#include<iostream>
class classA
{ 
private:
	int a;
	int b;
public:
	//classA(const classA & ca) //拷貝函數,如果沒有定義,則自動生成
	//{

	//}
	classA()
	{

	}
	classA(int x,int y):a(x),b(y)//構造函數
	{
		/*a = x;
		b = y;*/
	}
	void print()
	{
		std::cout << a << ' ' << b << std::endl;
	}
};
void main1()
{	 /*編譯器會默認生成默認構造函數和默認拷貝構造函數*/
	classA class1(7,8);
	classA class2(class1);
	class1.print();
	class2.print();
	std::cin.get();
}
class myclassA
{
public:
	//myclassA() = delete; //刪除默認構造函數
	myclassA() = default;//默認生成構造函數
	myclassA(const myclassA & )=delete;//刪除默認拷貝構造函數
	//~myclassA();
};

void main2()
{
	myclassA myclass1;

}
2>深度拷貝構造與淺拷貝構造
淺拷貝,兩個指針指向同一片內存,對內存中的值進行更新。深拷貝,重新申請內存,將傳遞過來的數據存儲在新的內存中。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
class string
{
public:
	char *p;
	int length;
	//獲取內容,分配內存,拷貝內容
	string(int num,char *str)
	{
		length = num;
		p = new char[length];
		memset(p, 0, length);
		strcpy(p,str);
	}
	string(const string &string1)
	{	 //淺拷貝
		//this->p = string1.p;
		//this->length = string1.length;
		//深拷貝,重新申請內存,將內容拷貝到新的內存空間中,被拷貝的內存空間被銷燬,不影響目前的內存空間
		this->length = string1.length;
		this->p = new char[this->length];
		memset(p, 0, length);
		strcpy(this->p,string1.p); //字符串的拷貝
	}
	~string()
	{
		delete[]p;//銷燬內存
	}
};
void main()
{
	string str1(10,"hello!");
	string str2(str1);
	std::cout << str1.p << std::endl;
	std::cout << str2.p << std::endl;
	string *pstr = new string(10, "hello!");
	string *pstrr = new string(*pstr);
	delete pstr;
	std::cout << pstrr->p << std::endl; //(*pstr).p
	std::cin.get();
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章