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 指针进行关联的。

猜你喜欢

转载自blog.csdn.net/weixin_42896619/article/details/84375935