以下为我练手的学生成绩查询代码段,共有两个类,一个是Score类,我想把它设为私有类,另一个为Manager类,Manager为Score类的友元。
Score.h
#include <map>
#include <string>
#include <iostream>
#ifndef SCORE_H
#define SCORE_H
struct Score
{
friend class Manager;
typedef std::map<std::string,double> scMap;
typedef std::map<std::string,double>::value_type index;//pair类型
Score():scoreMap(){}
Score(scMap &s):scoreMap(s){}
Score(index &i){scoreMap.insert(i);}
void updateScore(const std::string &,double);//根据科目修改成绩
bool insertScore(index newScore)
{
if((scoreMap.insert(newScore)).second==true)
return true;
else
{
std::cout<<"this project's score has existed!"<<std::endl;
return false;
}
}
double requeryScore(const std::string &)const;
bool deleteSigleScore(const std::string &);
std::map<std::string,double> scoreMap;
};
#endif
Score.cpp
#include "StdAfx.h"
#include <iostream>
#include "Manager.h"
#include "Score.h"
void Score::updateScore(const std::string &pro,double newScore)
{
if(scoreMap.count(pro))
{
scoreMap[pro]=newScore;
}
else
{
std::cout<<"This student's "<<pro<<"don't exist!"<<std::endl;
}
}
double Score::requeryScore(const std::string & sc)const
{
if(scoreMap.count(sc))
{
double newScor=(*(scoreMap.find(sc))).second;
return newScor;
}
else
{
std::cout<<"This student's "<<sc<<"don't exist!"<<std::endl;
return 0;
}
}
bool Score::deleteSigleScore(const std::string &spro)
{
if(scoreMap.erase(spro))
{
return true;
}
else
return false;
}
Manager.h
#pragma once
#include <map>
#include <string>
#include <iostream>
#include "Score.h"
#ifndef MANAGER_H
#define MANAGER_H
class Manager
{
typedef std::map<std::string,Score> studentMap;
public:
//只添加学生,不添加成绩
bool add(const std::string &);
//同时添加姓名以及成绩
bool add(const std::string &,Score::index);
bool add(const std::string &,Score::scMap &);
/*void insertScore(const std::string &,*/
bool deleteStu(const std::string &);
bool deleteScore(const std::string &,const std::string &);
bool updateName(const std::string &,const std::string &);
bool updateScore(const std::string &,const std::string &,double);
double querySingleScore(const std::string &,const std::string &);
std::map<std::string,double> queryAllScore(const std::string &);
private:
std::map<std::string,Score> stuMap;
};
#endif
Manager.cpp
#include "StdAfx.h"
#include "Manager.h"
#include <iostream>
#include <utility>
#include <iostream>
#include <map>
bool Manager::add(const std::string &sname)
{
if(stuMap.count(sname))
{
std::cout<<sname<<"has existed"<<std::endl;
return false;
}
else
{
std::pair<std::string,Score> newP;
newP.first=sname;
newP.second=Score();
stuMap.insert(newP);
}
}
bool Manager::add(const std::string &sname,Score::index scor)
{
if(stuMap.count(sname))
{
stuMap[sname].insertScore(scor);
return true;
}
else
{
stuMap.insert(std::make_pair(sname,Score(scor)));
return true;
}
}
bool Manager::add(const std::string &sname,Score::scMap &sCore)
{
if(stuMap.count(sname))
{
std::cout<<sname<<"has existed"<<std::endl;
return false;
}
else
{
stuMap.insert(std::make_pair(sname,sCore));
return true;
}
}
bool Manager::deleteStu(const std::string &sname)
{
if(stuMap.erase(sname))
{
std::cout<<sname<<"has delelted"<<std::endl;
return true;
}
else
{
std::cout<<sname<<"delete fail"<<std::endl;
return false;
}
}
bool Manager::deleteScore(const std::string &sname,const std::string &project)
{
studentMap::iterator stu=stuMap.find(sname);
if(stu!=stuMap.end())
{
return (stu->second).deleteSigleScore(project);
}
else
{
return false;
}
}
bool Manager::updateName(const std::string &oldName,const std::string &newName)
{
studentMap::iterator iter=stuMap.find(oldName);
if(iter!=stuMap.end())
{
add(newName,iter->second.scoreMap);
return true;
}
else
{
std::cout<<oldName<<"did not existed"<<std::endl;
return false;
}
}
bool Manager::updateScore(const std::string &stuName,const std::string &projName,double newScore)
{
studentMap::iterator iter=stuMap.find(stuName);
if(iter!=stuMap.end())
{
iter->second.updateScore(projName,newScore);
return true;
}
else
return false;
}
double Manager::querySingleScore(const std::string &sname,const std::string &proj)
{
studentMap::iterator iter=stuMap.find(sname);
/*if(iter!=stuMap.end())
{*/
double newScor=iter->second.requeryScore(proj);
return newScor;
/*}*/
}
std::map<std::string,double> Manager::queryAllScore(const std::string &sname)
{
studentMap::iterator iter=stuMap.find(sname);
return iter->second.scoreMap;
}
主程序
#include "stdafx.h"
#include "Manager.h"
#include <iostream>
#include <map>
#include <utility>
static enum choice
{
Query,
Delete,
Update,
Add
};
Manager manager;
void queryN()
{
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter the name you want to query:"<<std::endl;
std::string studentName,projectName;
if(std::cin>>studentName)
{
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter the project name you want to query"<<std::endl;
while(std::cin>>projectName)
{
double tempScore=manager.querySingleScore(studentName,projectName);
std::cout<<studentName<<"'s "<<projectName<<"is "<<tempScore<<std::endl;
}
}
std::cin.clear();
}
void cmdDelete()
{
//delete student
std::cout<<"*******************"<<std::endl;
std::cout<<"What's info do you want to delete ?(0:Student,1:Student's score)"<<std::endl;
int i;
std::string nameDele,projDele;
std::cin>>i;
switch(i)
{
case 0:
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter the name the student you want to delete"<<std::endl;
while(std::cin>>nameDele)
{
if(manager.deleteStu(nameDele))
std::cout<<nameDele<<"deleted"<<std::endl;
else
std::cout<<nameDele<<"deleted fail"<<std::endl;
}
break;
case 1:
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter the name the student you want to delete"<<std::endl;
while(std::cin>>nameDele)
{
std::cout<<"Please enter the project that you want to delete"<<std::endl;
while(std::cin>>projDele)
{
if(manager.deleteScore(nameDele,projDele))
std::cout<<nameDele<<"'s"<<projDele<<"succeed"<<std::endl;
else
std::cout<<nameDele<<"'s"<<projDele<<"fail"<<std::endl;
}
}
break;
}
std::cin.clear();
}
void updateInfo()
{
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter what info do you want to update?(0:stdudent's name 1:score"<<std::endl;
int i;
std::string queryName,newName,projName;
double newScore;
std::cin>>i;
switch(i)
{
case 0:
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter the name you want to update"<<std::endl;
std::cin>>queryName;
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter new name"<<std::endl;
std::cin>>newName;
if(manager.updateName(queryName,newName))
{
std::cout<<"*******************"<<std::endl;
std::cout<<queryName<<" has changed to "<<newName<<std::endl;
}
else
{
std::cout<<"*******************"<<std::endl;
std::cout<<"change fail"<<std::endl;
}
break;
case 1:
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter the name you want to update"<<std::endl;
std::cin>>queryName;
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter project name you want to update"<<std::endl;
std::cin>>projName;
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter the new score "<<std::endl;
std::cin>>newScore;
if(manager.updateScore(queryName,projName,newScore))
{
std::cout<<"*******************"<<std::endl;
std::cout<<queryName<<"'s"<<projName<<" has changed to "<<newScore<<std::endl;
}
else
{
std::cout<<"*******************"<<std::endl;
std::cout<<"change fail"<<std::endl;
}
break;
}
std::cin.clear();
}
void cmdAdd()
{
std::string newName,newProj;
double newScore;
do{
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter the new name,enter 'q' to finish"<<std::endl;
std::cin>>newName;
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter the new project"<<std::endl;
while(std::cin>>newProj)
{
std::cout<<"*******************"<<std::endl;
std::cout<<"Please enter the new score"<<std::endl;
if(std::cin>>newScore)
{
manager.add(newName,std::make_pair(newProj,newScore));
}
}
}while(std::cin&&newName!="q");
}
int _tmain(int argc, _TCHAR* argv[])
{
int choiceInt;
do{
std::cout<<"Please choose the function you want to do:"<<std::endl;
std::cout<<"*******************"<<std::endl;
std::cout<<"0:Query"<<std::endl<<"1:Delete"<<std::endl<<"2:Update"<<std::endl<<"3:Add"<<std::endl;
std::cin>>choiceInt;
switch(choiceInt)
{
case 0:
queryN();
std::cin.clear();
break;
case 1:
cmdDelete();
std::cin.clear();
break;
case 2:
updateInfo();
std::cin.clear();
break;
case 3:
cmdAdd();
std::cin.clear();
break;
}
}while(std::cin);
return 0;
}
我是把Manager的数据成员定义成string-Score的Map容器,但是我想把Score设为私有类只有Manager类可访问,这样Score就不能作为容器的元素,设为指针?也不行啊。大神可以指导一下么?
迷茫2017-04-17 13:17:33
Place the declaration of the Score class as a private member in the declaration of the Manager class:
//Manager.h
class Manager{
public:
//some public declarations
private:
class Score{
public:
//public members
private:
//private members go here
};
//std::map<std::string, Score*> someMap;
typedef std::shared_ptr<Score> ScorePtr;
std::map<std::string, ScorePtr> anotherMap;
};
In this way, the Score class in your Manager class is private. When others try to instantiate a Score compiler will report an error:
Manager::Score score;//error, class Manager::Score is private
Then every time you need to insert this Map, you use std::make_shared<Score> to wrap it up and pass it in.