我有以下问题:我有一个Data类,它在一个向量中存储字符串,以及从它派生的两个类:Team和Player。我想制作一个索引表,以便用一个存储与字符串相关的整数的映射来表示,例如。播放器的ID存储在向量的第0个位置。这是代码(不详细):
class Data{
protected:
std::vector<std::string> data;
//etc.
};
class Player:public Data{
static std::map<std::string, int> table_of_indices;
public:
std::string operator[](const std::string& str) {return data[table_of_indices[str]];}
};
class Team:public Data{
static std::map<std::string, int> table_of_indices;
public:
std::string operator[](const std::string& str) {return data[table_of_indices[str]];}
};
问题在于两个派生类看起来完全相同,因为它们的地图内容是不同的。但是,有没有办法在某种程度上包含元素访问运算符和Data类中的索引表,然后分别初始化Player和Team类的映射?
答案 0 :(得分:4)
首先,这不是一个好的客观编程。你应该问自己一个问题:&#34;玩家是数据吗?&#34;和#34;团队是数据吗?&#34;。答案是否定的,因此玩家和团队不应该来自Data
。
您应该使用此附加元素扩展您的Data
类,然后在Player
和Team
中使用它。
您的新Data
课程应类似于:
class Data{
std::vector<std::string> data;
std::map<std::string, int> table_of indices;
//etc.
public:
std::string operator[](const std::string& str) {return data[table_of_indices[str]];}
};
然后,您可以使用不同的map
初始化它以用于不同的用途。
为了避免克隆整个map
,您可以使用指针代替map:
std::map<std::string, int>* table_of indices;
然后在Data
构造函数中,您可以设置指针:
public Data(std::map<std::string, int>* table_of_indices) {
this.table_of indices = table_of_indices;
}
现在在Player
内你仍然可以拥有静态地图。另外,您应该添加Data
实例。
class Player {
static std::map<std::string, int> table_of indices;
Data *player_data;
public:
std::string operator[](const std::string& str) {return *player_data[str];}
Player() { player_data = new Data(&Player::table_of_indices); }
~Player() { delete player_data; }
};
答案 1 :(得分:3)
这是CRTP的工作!
template <class Tderived>
struct DataIndexer : Data {
friend struct Tderived;
std::string const &operator [] (const std::string& str) const {
return data[table_of_indices[str]];
}
private:
DataIndexer() {}
static std::map<std::string, int> table_of_indices;
};
现在,您可以从Player
继承DataIndexer<Player>
,并且新的实例将拥有自己的静态成员。