Bootstrap

C++学习完整案例

Hello, 大家好,我是爱吃香蕉的猴子,今天找个例子,练练C++


转载


CStudent.h

#ifndef C_STUDENT_H
#define C_STUDENT_H
#include <string>
#include <iostream>

class CStudent
{
	/* 友元函数
	 *  类的友元函数是定义在类外部,但有权访问类的所有私有
	 *(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,
	 *但是友元函数并不是成员函数。
	 */

	//operator 是C++的一个关键字,它和运算符(如=)一起使用,
	//表示一个运算符重载函数,在理解时可将operator和运算符(如operator=)视为一个函数名
	friend std::ostream & operator<<(std::ostream & os, CStudent & stu);
	friend std::istream & operator>>(std::istream & is, CStudent & stu);

public:

	CStudent();
	~CStudent();

	int getId() const;
	void setId(int val);

	std::string getName() const;
	void setName(std::string val);

	int getAge() const;
	void setAge(int val);

	
private:

	int id;
	std::string name;
	int age;
	
};


#endif

/*
 友元的解释
#include <iostream>

using namespace std;

class Box
{
   double width;
public:
   friend void printWidth( Box box );
   void setWidth( double wid );
};

// 成员函数定义
void Box::setWidth( double wid )
{
	width = wid;
}

// 请注意:printWidth() 不是任何类的成员函数
void printWidth( Box box )
{
   // 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 
cout << "Width of box : " << box.width << endl;
}

// 程序的主函数
int main()
{
	Box box;

	// 使用成员函数设置宽度
	box.setWidth(10.0);

	// 使用友元函数输出宽度
	printWidth(box);

	return 0;
}
*/

CStudent.cpp

#include <iostream>
#include <string>
#include "CStudent.h"
using namespace std;

// 学生默认id是-1,说明这暂时是一个无效的学生。
CStudent::CStudent(){
	this->id = -1;
}
CStudent::~CStudent(){}


//不需要再改变的就使用const
int CStudent::getId() const { return id; }
void CStudent:: setId(int val) { id = val; }

std::string CStudent:: getName() const { return name; }
void CStudent:: setName(std::string val) { name = val; }


int CStudent:: getAge() const { return age; }
void CStudent:: setAge(int val) { age = val; }


std::ostream & operator<<(std::ostream & os, CStudent & stu) {

	os<<stu.getId()<<"     "<<stu.getName()<<"     "<<stu.getAge();

	return os;
}

std::istream & operator>>(std::istream & is, CStudent & stu) {
	is>>stu.id>>stu.name>>stu.age;
	return is;
}

CStudentMg.h

#ifndef C_STUDENT_MG_H
#define C_STUDENT_MG_H
#include "CStudent.h"
#include <map>
#include <string>

using namespace std;

class CStudentMg
{
public:

	CStudentMg();
	~CStudentMg();

	// 增
	CStudent addAStu(std::map<int,CStudent> & m1,CStudent & stu);

	// 删
	bool deleteStuById(std::map<int, CStudent> & m1,const int & id);

	// 改
	CStudent updateStu(std::map<int, CStudent> & m1, const CStudent & stu);

	// 查 by id
	CStudent findById(const std::map<int, CStudent> & m1, const int & id) const;
	// showAll
	void showAll(const std::map<int, CStudent> & m1 ) const;
	
	// save to file
	bool saveToFile(const std::map <int,CStudent> & m1,const std::string & pathName) const;

	// read from file
	bool readFromFile(std::map<int, CStudent> & m1, std::string path);
	

private:

};

#endif

CStudentMg.cpp

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <sstream>
#include "CStudent.h"
#include "CStudentMg.h"

using namespace std;


CStudentMg::CStudentMg()
{
}

CStudentMg::~CStudentMg()
{
}

//int &b=a; //b是a的引用,加后对b操作就是对a操作!
//这里&就是一个引用,之前理解取地址,是取的逻辑地址,物理地址是指针指向的地址;
//这个实际上是C++里的形参符号,必须要在跟在数据类型的后面使用。在函数内部对形参的操作都等同于直接操作原变量。

// 增
CStudent CStudentMg:: addAStu(map<int,CStudent> & m1,CStudent & stu) {
	
	// 先假设id可以重复了
	m1.insert(make_pair(stu.getId(),stu));
	return stu;
}


// 删
bool  CStudentMg:: deleteStuById(map<int, CStudent> & m1, const int & id) {

	bool b = false;

	map<int,CStudent> ::iterator iter;
	iter = m1.find(id);
	if (iter!=m1.end())
	{
		m1.erase(iter);
		b = true; // 删除成功
	}
	
	return b;
}



// 改
CStudent CStudentMg:: updateStu(map<int,CStudent> & m1,const CStudent & cStu) {

	// 迭代器是一个smart point!
	// 是可以通过迭代器去访问到 m1里的东西,并且做出修改的!
	// 除非迭代器是const迭代器

	CStudent stu;
	int id = cStu.getId();
	
	map<int,CStudent> :: iterator iter;
	iter = m1.find(id);
	if (iter!=m1.end())
	{
		// 修改
		iter->second = cStu;
		stu = cStu; // 把修改后的对象,赋值,再返回上层
	}

	return stu;
}


// 查 by id
CStudent  CStudentMg:: findById(const map <int, CStudent> & m1, const int & id) const{

	CStudent stu ;

	map<int,CStudent> ::const_iterator iter;
	iter = m1.find(id);
	if (iter!=m1.end())
	{
		stu = iter->second;
	}

	return stu;
}


// showAll
void  CStudentMg:: showAll(const map<int,CStudent> & m1) const{

	for (auto p : m1)
	{
		cout<<p.second<<endl;
	}
	
}


// save to file
bool CStudentMg::saveToFile(const map <int,CStudent> & m1,const string & pathName) const{

	bool b = true;

	//fstream ofs(pathName,ios::out+ios::binary); // 为什么不是以binary保存?
	fstream ofs(pathName,ios::out);
	if (ofs) {
		stringstream ss;

		cout<<"文件打开"<<endl;
		
		CStudent stu;
		for (auto p = m1.begin();p!=m1.end();p++)
		{
			stu = p->second;
			ss<<stu<<endl;
		}
		
		ofs<<ss.str(); // 注意,输出一定是 ss.str();
		
		ofs.close();
	}
	else
	{
		cout<<"文件打开失败"<<endl;
		b = false;
	}

	return b;
}


// read from file
bool CStudentMg:: readFromFile(map<int,CStudent> & m1, string path) {
	bool b = true;

	m1.clear(); // 清掉原来的
	
	fstream ifs(path,ios::in);
	if (ifs) {
		cout<<"文件打开"<<endl;
		string s;
		stringstream ss;
		while (getline(ifs,s)) // 怎么一行行地读取?
		{
			CStudent cStu;
			ss<<s;
			// cout<<ss.str();
			ss>>cStu;
 			ss.clear();

			m1.insert(make_pair(cStu.getId(),cStu));
			
		}

		ifs.close();

	}
	else {
		cout<<"文件打开失败"<<endl;
		b = false;
	}

	return b;
}

CMainView.h


#ifndef C_MAIN_VIEW_H
#define C_MAIN_VIEW_H

#include <iostream>
#include <map>
#include <string>
#include "CStudent.h"
#include "CStudentMg.h"

class CMainView
{
public:
	CMainView();
	~CMainView();


	/* 欢迎 */
	void welcome();

	/* 显示菜单 */
	void showMenu();

	/* view 显示所有学生 */
	void showAllStuAtView(const std::map<int, CStudent> & stu_m1);

	/* view层 添加一个学生 */
	void addStuAtView( std::map<int, CStudent> & stu_m1 );

	/* view 查找一个学生 */
	void findStuAtView(const std::map<int, CStudent> & m1) ;

	/* view层删除一个学生 */
	void deleteByIdAtView(std::map<int, CStudent> & v1);

	/* view层 更新一个学生 */
	void updateByIdAtView(std::map<int, CStudent> & m1);

	/* view层 把map保存进文件 */
	void saveToFileAtView(const std::map<int, CStudent> & m1, std::string pathName);

	/* view层 把文件中的东西导入 map */
	void readFromFileAtView(std::map<int, CStudent> & m, std::string pathName);

private:

};
#endif

main_1.cpp

/************************************************************************/
/* 
* student management 1 
* v1.2
* 更加OOP的版本
* 把界面的函数,也封到CMainView里面了
*
* v1.1
* qcy
* 2016年11月28日18:50:49
* 
* 分层。MVC。
* 
* 1. 学生信息录入 (姓名、年龄、id)
* 2. 学生信息修改
* 3. 学生删除
* 4. 显示
* 5. 根据id查找
* 6. 保存至文件
* 7. 从文件恢复
* 
/************************************************************************/

#include <iostream>
#include <string>
#include <map>
#include "CStudent.h"
#include "CStudentMg.h"
#include "CMainView.h"

using namespace std;

int main() {

	string pathName = "d:/student_manegement.txt";

	map<int, CStudent> stu_v1;
	
	CMainView cView;

	cView.welcome();
	cView.showMenu();

	string operateType;
	cin>>operateType;

	while (operateType!="0")
	{
		if (operateType=="1") {// 录入
			cView.addStuAtView(stu_v1); // 因为要对这个修改
		}
		else if(operateType=="2") { // 修改
			cView.updateByIdAtView(stu_v1);
		}
		else if(operateType=="3") { // 查找
			cView.findStuAtView(stu_v1);
		}
		else if (operateType=="4") {
			cView.deleteByIdAtView(stu_v1);
		}
		else if( operateType == "5") { // 显示所有
			cView.showAllStuAtView(stu_v1);
		}
		else if( operateType=="6") {  // 保存至文件
			cView.saveToFileAtView(stu_v1,pathName);
		}
		else if(operateType=="7") {// 从文件读取
			cView.readFromFileAtView(stu_v1,pathName);
		}
		else {
			
			cView.welcome();
			cView.showMenu();
		}

		cin>>operateType;
	}

	return 0;
}

                                               Code的搬运工V1.0
;