【问题标题】:C++ exceptions with unused variables带有未使用变量的 C++ 异常
【发布时间】:2015-02-01 11:57:29
【问题描述】:

我有一个地图类模板,用于存储我的通用数据类型。我必须使用字符串来索引地图类。如果尝试访问未初始化的元素,我需要抛出未初始化的异常。主要是这样的:

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 附近移动)而不是抛出异常。问题是我不知道应该在代码的哪一部分抛出异常,也不知道检查变量是否未初始化的方法。 我会很感激任何帮助。

【问题讨论】:

  • 那么你的throw呢?
  • 你知道你可以在你的推回之后通过简单地使用nodeArray.back()来压制整个nodeArray[max]逻辑。

标签: c++ exception initialization throw


【解决方案1】:

您当前的operator[] 不区分读取权限和项目的原始创建。因此,它不能因使用不存在的项目而引发异常,因为就它而言,与该项目的原始创建没有区别。

在现有设计的限制下,有各种技术解决方案(没有一个很好),特别是

  • 您可以让operator[] 返回一个代理对象,该对象的赋值运算符创建一个项目,并将其转换为项目类型访问现有项目。

但是鉴于给定的代码仍然存在非常基本的问题,我不建议这样做。

相反,放弃当前的设计。要么使不存在的项目的访问默认创建一个新项目,要么使创建和访问的操作不同。前者是std::map 所做的,后者可能是最简单的。

【讨论】:

  • 感谢您的反馈!!我想我会尝试使创建和访问的操作与众不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-20
  • 2017-11-22
  • 2011-04-25
  • 2016-05-06
相关资源
最近更新 更多