第七十七讲 细说map(3)

上一讲我们说了泛化的复制构造函数,现在我们回来继续看看map,但是再说继续说map之前我觉得我们有必要先把pair弄清楚,其实也没什么好说的了,但是有一个函数我们是一定要知道的:
——————————–
template<typename T,typename U>
pair<T,U>make_pair(T&

t,U&

u){

return pair<T,U>(t,u);



}
———————————

不难发现,这是一个生成pair的函数,我们可以直接使用这个函数得到一个pair,而不必去指明pair类型。关于pair,我们说到这里就差不多了,他的存在多数是为了作为辅助来用,所以我们现在继续回来看看map,在上上讲里我们说了map里面的一些必要的typedef,所以现在我们来接着往下看关于map的一些操作:
———————————–
template<typename Key,typename T,typename Cmp=less<Key>,

typename A=allocator<pair<const Key,T
>>>
class map{
public:

/////

// ///


mapped_type&

operator[](const Key_type&

k);



/////
};


————————————-
这个操作符对现在的我们来说已经司空见惯了,不过不能否认这是一个极为好用的操作,因为我们通常都是用这个下标操作符来操作map的,比如:
————————————

void f(){

map<string, int>m;


m["

Math"

] = 80;


m["

English"

] = 92;


m["

Chinese"

] = 85;


map<string, int>::iterator it = m.begin();


while (it != m.end()){

cout <<it->
first <<"

t"

<<it->second <<endl;


it++;


}
}
———————————-

还记得以前给大家的一个练习吗?那是一位同学提出来的,就是怎么设计一个学生成绩的类,当时我把这个任务扔给大家,因为我想大家肯定有办法解决这个问题,现在我们再回去看这个问题,是不是发觉很简单了呢?如同上面一样,我们用一个map来储存成绩,然后再用map来存储学生姓名和成绩:
———————————–
map<string,map<string,double>>
———————————-

听起来有些复杂,确实是有些复杂的,不是正好我们说到map吗?好啊,反正就算是小试牛刀吧,我就简单的弄个出来看看吧:
———————————–
//Students.h
#ifndef _STUDENTS_H_
#define _STUDENTS_H_
#include <map>
#include <string>
using namespace std;


typedef map<string,double>Data_type;


typedef map<string,Data_type>MyType;


namespace My_Code{

class Students{

public:

Students();


~Students();


void AddStudent(const string&

name,Data_type&

data);


Data_type&

GetScore(const string&

name);


MyType&

GetName();


private:

MyType _name;


};


}
#endif
————————————

实现也很简单,仅作为参考:
————————————
//Students.cpp
#include "

Students.h"


using namespace My_Code;

Students::Students()
{


_name = MyType();


}

Students::~Students()
{
}


void Students::AddStudent(const string&

name,Data_type&

data){

_name[name] = data;


}

Data_type&

Students::GetScore(const string&

name){

return _name[name];


}

MyType&

Students::GetName(){

return _name;


}
———————————
然后,我们可以这样用:
———————————–
//TestStudents.cpp
#include <iomanip>
#include <iostream>
#include "

Students.h"


using namespace std;


using namespace My_Code;


int main()
{

Students s;



Data_Type m;



m["

Math"

] = 60;



m["

English"

] = 70;



m["

Chinese"

] = 80;



s.AddStudent("

ZhangSan"

,m);

//为了方便,所以我们都使用同一份成绩

s.AddStudent("

LiSi"

,m);



s.AddStudent("

WangEr"

,m);



MyType::iterator it = s.GetName().begin();



while(it != s.GetName().end()){ //遍历所有学生和打印出其成绩

cout<<it->
first<<"

:n"

;


Data_type::iterator _it = it->second.begin();


while(_it != it->second.end()){

cout<<setw(20)<<_it->
first<<"

: "

<<_it->second<<endl;


_it++;


}

it++;


}

_it = s.GetScore("

ZhangSan"

).begin();


cout<<"

ZhangSan:n"

;


while(_it != s.GetScore("

ZhangSan"

).end()){ //获取ZhangSan的成绩

cout<<setw(20)<<_it->
first<<"

: "

<<_it->second<<endl;


_it++;


}

return 0;


}
————————————–

这个类使用起来有些复杂不人性化,只要我们愿意,我们可以把写得更加好用一些,当然碍于篇幅的原因,这里我们就不多说了,希望曾经提问的同学还能够坚持下去,能够看到今天我们的实现方案,虽然不能拿出去商用,但可以作为参考,我坚持C++的原因就是这里:100个Java程序员写出的代码都是一种风格,而100个C++程序员写出来的程序就有100种风格。晕死,说了这么多,还是没说到重点,重点就是我们今天所说的operator[]的应用啦,我们使用map,很多情况下是通过operator[]来使用的。

今天好像说得不少了哦,算了吧,今天就先到这里吧,我们下周再见。


=================================
回复D直接查看目录


原文始发于微信公众号(

C/C++的编程教室

):第七十七讲 细说map(3)

|

发表评论