1. 程式人生 > >C++學習 18-11-22

C++學習 18-11-22

1.昨天的 連結串列類

1.首先確定連結串列類都需要一些什麼

1.需要定義一個節點來存放內容,typedef struct NODE;
2.需要 連結串列的頭指標、尾指標以及連結串列的長度資訊
3.連結串列類的建構函式以及解構函式;
4.連結串列類的成員函式:在末尾新增節點 PushBack、在表頭彈出節點 PopFront、顯示連結串列資訊;

class CList
{
private:
	typedef struct NODE
	{
		int n_value;
		struct NODE *p_next;
	}Node;

private:
	Node *n_p_head;
Node *n_p_end; int n_length; public: CList() { n_p_head = 0; n_p_end = 0; n_length = 0; } CList(int count, int value) { n_p_head = 0; n_p_end = 0; n_length = 0; for(int i=0; i<count; i++) { PushBack(value); } } ~CList() { while(n_p_head) PopFront(); } public: void
PushBack(int value) { Node *p_new_node = new Node; p_new_node->n_value = value; p_new_node->p_next = 0; if(n_p_head) { n_p_end->p_next = p_new_node; } else { n_p_head = p_new_node; } n_p_end = p_new_node; ++n_length; } void PopFront() { // 沒有節點 if(!n_p_head)
{ return; } // 只有一個節點 else if(n_length == 1) { n_p_head = 0; n_p_end = 0; n_length = 0; } // 有兩個及兩個以上節點 else { Node *p_flag = n_p_head; n_p_head = n_p_head->p_next; delete p_flag; p_flag = 0; --n_length; } } void ShowList() { Node *p_temp = n_p_head; while(p_temp) { cout << p_temp->n_value << " "; p_temp = p_temp->p_next; } cout << "Size:" << n_length << endl; } }; int main() { CList cls1; cls1.ShowList(); CList cls2(3, 100); cls2.ShowList(); CList cls3; cls3.PushBack(1); cls3.PushBack(2); cls3.PushBack(3); cls3.PushBack(4); cls3.ShowList(); cls3.PopFront(); cls3.ShowList(); system("pause"); return 0; }

2.將學生資訊通過連結串列類儲存

1.步驟流程

1.首先需要一個學生類,用來儲存單個學生的資訊;
2.其次需要一個連結串列類,用來儲存多個學生的資訊。

1.首先建立一個學生類

class CStudent
{
private:
	int s_id;
	string s_name;

public:
	CStudent()
	{
		s_id = 0;
		s_name = "";
	}

public:
	void InitInfo(int id, string name)
	{
		s_id = id;
		s_name = name;
	}

	void ShowStudent()
	{
		cout << s_id << ":" << s_name << endl;
	}
};

2.其次建立一個連結串列類

class CList
{
private:
	typedef struct NODE
	{
		CStudent n_student;
		struct NODE *p_next;
	}Node;

private:
	Node *n_p_head;
	Node *n_p_end;
	int n_length;

public:
	CList()
	{
		n_p_head = 0;
		n_p_end = 0;
		n_length = 0;
	}

	~CList()
	{
		while(n_p_head)
			PopFront();
	}

public:
	void PushBack(CStudent& student)
	{
		Node *p_new_node = new Node;
		p_new_node->n_student = student;
		p_new_node->p_next = 0;

		if(n_p_head)
		{
			n_p_end->p_next = p_new_node;
		}
		else
		{
			n_p_head = p_new_node;
		}
		n_p_end = p_new_node;

		++n_length;
	}

	void PopFront()
	{
		// 沒有節點
		if(!n_p_head)
		{
			return;
		}
		// 只有一個節點
		else if(n_length == 1)
		{
			n_p_head = 0;
			n_p_end = 0;
			n_length = 0;
		}
		// 有兩個及兩個以上節點
		else
		{
			Node *p_flag = n_p_head;
			n_p_head = n_p_head->p_next;
			delete p_flag;
			p_flag = 0;
			--n_length;
		}	
	}

	void ShowList()
	{
		Node *p_temp = n_p_head;
		while(p_temp)
		{
			p_temp->n_student.ShowStudent();
			p_temp = p_temp->p_next;
		}
		cout << "Size:" << n_length << endl;
	}
};

int main()
{
	CStudent st1;
	st1.InitInfo(1, "AAA");
	CStudent st2;
	st2.InitInfo(2, "BBB");
	CStudent st3;
	st3.InitInfo(3, "CCC");

	st1.ShowStudent();
	st2.ShowStudent();
	st3.ShowStudent();

	CList cls;
	cls.PushBack(st1);
	cls.PushBack(st2);
	cls.PushBack(st3);
	cls.ShowList();



	system("pause");
	return 0;
}

3.物件的種類

0.首先定義一個類

class CPerson
{
public:
	CPerson()
	{
		cout << "CPerson" << endl;
	}

	~CPerson()
	{
		cout << "~CPerson" << endl;
	}
};

1.棧區物件

其生命週期到作用域結束。

int main()
{
	CPerson ps1;

	system("pause");
	return 0;
}

當執行上述程式碼,在return 0處下斷點時,螢幕顯示:CPerson,當執行至return 0時作用域結束,顯示 ~CPerson。

2.堆區指標物件

其生命週期 直到遇到 delete。

int main()
{
	CPerson *ps2 = new CPerson;

	delete ps2;
	ps2 = 0;

	system("pause");
	return 0;
}

若沒有 delete,則在螢幕上只會顯示 CPerson,而不顯示 ~CPerson。

3.全域性物件

其生命週期到程式結束。

CPerson ps3;
int main()
{
	
	system("pause");
	return 0;
}

執行上述程式碼,在大括號處下一個斷點,其在return 0處並不顯示 ~CPerson。

4.臨時物件

其生命週期僅有這一行。

int main()
{
	CPerson();


	system("pause");
	return 0;
}
一般只有函式的返回值會建立臨時物件
CPerson QQ()
{
	CPerson ps;
	return ps;
}

int main()
{
	CPerson pp;
	pp = QQ();


	system("pause");
	return 0;
}

此時會在螢幕上顯示兩個 CPerson 和兩個 ~CPerson。

5.大部分物件都是new出來的,需要自己控制生命週期

6.new和delete可以觸發建構函式和解構函式,而malloc和free並不會觸發建構函式和解構函式,這就是為什麼在C++中推薦使用new而不是用malloc了。

7.this指標

1.概念

C++程式設計:在每一個成員函式中都包含一個特殊的指標,這個指標的名字是固定的,成為 this,它是指向本類物件的指標,它的值是當前被呼叫的成員函式所在的物件的起始地址。

百度百科:一個物件的this指標並不是物件本身的一部分,不會影響sizeof(物件)的結果。this作用域是在類內部,當在類的非靜態成員函式中訪問類的非靜態成員的時候,編譯器會自動將物件本身的地址作為一個隱含引數傳遞給函式。

2.理解

首先,對於一個空類,類似下列的一個類:

class CPerson
{
public:
	void Show()
	{
		cout << "Hello" << endl;
	}
};
類CPerson的大小(sizeof)為1,該類是一個空類。
類的成員變數是在建立物件的時候存在,每個物件都有份,當建立類似 CPerson *p = NULL 的指標時,p可以進行呼叫函式,但是不可以使用成員變數(public的成員變數)。
成員函式是函式編譯期存在,只有一份。
不同物件的引數可以在同一個函式中使用,類會自動將呼叫函式的物件的地址傳入函式,傳入的指標就是this,指代當前的物件。
成員變數和成員函式是由 this 指標進行關聯的。