2

我想做一些异常处理。我打算使用__LINE__and__FILE__宏。

我有一些头文件 Vectors.hpp,我在其中为向量结构实现了一些类。在这个类中,我实现了operator [],并且每次将此运算符与越界索引一起使用时,我都想抛出一个异常。我在一些源代码 test.cpp 中测试这个类。然后我希望能够在 test.cpp 中看到发生这种情况的确切行。

但是我知道__LINE__每次包含一些标题时宏都会被禁用,所以我得到的是 Vectors.hpp 中处理异常的行,而不是 test.cpp 中的行。有没有一个很好的方法来解决这个问题?或者,如何实现自己的__LINE__宏?

4

3 回答 3

5

__LINE__宏永远不会被禁用。它在你写它的地方展开。有两种编写代码的方法(更准确地说,有两种生成令牌的方法):

  • 手动写
  • 使用预处理器编写代码

如果你有它是foo.cpp这样的文件(只是示例性的,实际上这是非常糟糕的代码)

class Foo {
public:
    Frob operator[] (size_t) { throw __LINE__ }
};

then__LINE__总是 3 并且__FILE__总是foo.cpp

那是因为宏在使用它们的地方被扩展。解决方案是找到一种方法将它们扩展到您想要的位置,唯一的方法是定义另一个宏:

#define safe_subscript(foo, index) \
      try {foo[index];} \
      catch(...) { std::cout << __LINE__ << '\n'; }

....
safe_subscript(foo, 256);

但是正如您所看到的,这会导致非常丑陋的代码和变通方法。

真正的解决方案:只要在越界()时抛出异常throw std::out_of_range,或者像标准库那样做:

T& operator[] (size_type i) { return store_[i]; }
T& at (size_type i) { if (i>size_) throw std::out_of_range("crap");
                      return store_[i]; }

T operator[] (size_type i) const { return store_[i]; }
T at (size_type i) const { if (i>size_) throw std::out_of_range("crap");
                           return store_[i]; }

如果您的用户收到异常,他应该调试他/她/它发生编程错误的地方。

于 2012-07-31T15:40:30.627 回答
1

您可以将当前行作为异常的一部分传递。将您的例外定义为

struct MyException : public std::exception {
    MyException(const char* line) : errorLine(line);
    const char* errorLine;
};

并按如下方式使用它:

if (isError())
     throw MyException(__LINE__);
于 2012-07-31T15:42:50.260 回答
0

很简单,您必须在捕获异常时添加该信息,通常我们会创建一个扩展 std::exception 的类,并使用一些附加属性来安装明确的错误消息,在其上包含__LINE__,__FILE__甚至__FUNCTION__

这一个也回答了这个问题: 获取有关c++异常在catch块内的位置的信息?

于 2012-07-31T15:43:55.833 回答