我有一个地图类模板,我在其中存储我的通用数据类型。我必须使用字符串来索引map类。如果尝试访问未初始化的元素,我需要抛出一个未初始化的异常。主要看起来像这样:
mapClass <double> mc;
mc[”aaa”] = 3.5;
double var1 = mc[“aaa”];
cout << var1 << endl; //print 3.5
try{
double var2 = mc[“aab”]; //uninitialized error: throw exception
}catch( classMap<double>::Uninitialized&){
cout<< ”Uninitialized error…..”<<endl;
}
我的想法是在mapClass模板中创建一个节点类,它将存储键(字符串)和值(T)元素。我已经实现了一个operator []重载,它将返回对T元素的引用。如果向量内不存在给定的字符串,则此operator []重载也将push_back新元素。
template< typename T >
class mapClass{
public:
class Uninitialized{};
class Node{
public:
string key;
T value;
bool asigned;
Node(){
key = "";
asigned = false;
}
~Node(){}
};
mapClass(){
initialized=false;
max=0;
}
T& operator[](string a){
int ret;
bool out = false;
if (!initialized){
Node newNode;
nodeArray.push_back(newNode);
nodeArray[0].key = a;
initialized = true;
max = 0;
ret = 0;
}
else{
for (int i = 0; i <= max; i++){
if (nodeArray[i].key == a){
out = true;
ret = i;
}
}
if (!out){
max++;
ret = max;
Node newNode;
nodeArray.push_back(newNode);
nodeArray[max].key = a;
}
}
return nodeArray[ret].value;
}
private:
vector<Node> nodeArray;
bool initialized;
int max;
};
现在程序打印值3.5,但也打印一个值(在-8578623左右移动)而不是抛出异常。问题是我不知道代码的哪一部分应该抛出异常,我不知道检查变量是否未初始化的方法。 我感激任何帮助。
答案 0 :(得分:1)
您当前的operator[]
无法区分读取权限和项目的原始创建。因此,它不能为使用不存在的项目抛出异常,因为就其而言,与该项目的原始创建没有区别。
在现有设计的约束下,有各种技术解决方案(没有一个真正好),特别是
operator[]
返回一个代理对象,该代理对象的赋值运算符会创建一个项目,并且转换为该项目类型会访问现有项目。但是看到给定的代码仍然存在非常基本的问题,我不建议这样做。
相反,抛弃当前的设计。使访问不存在的项默认为创建新项,或使创建和访问操作不同。前者是std::map
所做的,后者可能是最简单的。