函数 operator[] 可以用于为类的对象定义下标运算的意义。
operator[] 的第二个参数(下标)可以具有任何类型,这就使得我们可以去定义vector ,关联数组(仿写map)。
eg:
用运算符重载的方式来进行词频统计,我们仿写一个关联数组:
class Assoc {
public:
Assoc() {}
const double& operator[](const std::string &n);
double& operator[](std::string &n);
//注意这里返回的是 & 引用,可以修改!
void print_all() const;
private:
struct Pair {
std::string name;
double val;
Pair(std::string n = "", double v = 0) : name(n), val(v) {}
};
std::vector<Pair> vec;
Assoc(const Assoc &elem); //forbidden
Assoc& operator=(const Assoc &elem); //forbidden
};
//这里等价于简单实现了map的 [] 操作
double& Assoc::operator[](std::string &n)
{
for (std::vector<Pair>::iterator i = vec.begin(); i != vec.end(); i++)
if (i->name == n)
return i->val;
vec.push_back(Pair(n, 0));
return vec.back().val;
}
total:
#include <iostream>
#include <vector>
class Assoc {
public:
Assoc() {}
const double& operator[](const std::string &n);
double& operator[](std::string &n);
void print_all() const;
private:
struct Pair {
std::string name;
double val;
Pair(std::string n = "", double v = 0) : name(n), val(v) {}
};
std::vector<Pair> vec;
Assoc(const Assoc &elem); //forbidden
Assoc& operator=(const Assoc &elem);
};
double& Assoc::operator[](std::string &n)
{
for (std::vector<Pair>::iterator i = vec.begin(); i != vec.end(); i++)
if (i->name == n)
return i->val;
vec.push_back(Pair(n, 0));
return vec.back().val;
}
const double& Assoc::operator[](const std::string &n)
{
for (std::vector<Pair>::iterator i = vec.begin(); i != vec.end(); i++)
if (i->name == n)
return i->val;
vec.push_back(Pair(n, 0));
return vec.back().val;
}
void Assoc::print_all() const
{
for (auto it = vec.begin(); it != vec.end(); it++)
std::cout<<it->name<<" : "<<it->val<<std::endl;
}
int main()
{
Assoc obj;
std::string temp;
while (std::cin >> temp)
obj[temp]++;
obj.print_all();
return 0;
}