例外和C风格的字符串

问题描述 投票:-2回答:2

我有异常问题:

#include <iostream>
#include <cstring>
#include <exception>

class except :public std::exception
{
    char* err;
public:
    except(const char* s) noexcept
    {
        err = new char[strlen(s) + 1];
        strcpy(err, s);
        err[strlen(s)] = 0; //is it necessary??
    }
    virtual const char* what() noexcept
    {return err;}
    virtual ~except() noexcept
    {delete err;}
};

double div(const double& a, const double& b) noexcept
{
    if (b == 0.0)
        throw except("DIVIDED BY 0");
    return a / b;
}

int main()
{
    try
    {
        std::cout << div(5.0, 0.0);
    }
    catch (std::exception &ex)
    {
        std::cout << ex.what();
    }
    return 0;
}

我想打印“DIVIDED BY 0”,但我得到:

terminate called after throwing an instance of 'except'
  what():  std::exception
Aborted

Process returned 134 (0x86)

我应该把noexcept放在每个不抛出任何异常的函数/成员函数中吗?

err[strlen(s)] = 0是必要的吗? (在except :: except(const char * s)中除外)

c++ exception
2个回答
2
投票

我想打印“DIVIDED BY 0”但我得到:在抛出“除外”的实例后终止调用

double div(const double& a, const double& b) noexcept

你声称你不会抛出异常,但你撒谎。结果是在实际抛出时调用std :: terminate。


2
投票

问题实际上是双重的。首先,正如@ manni66所暗示的那样,div不应该被声明为noexcept,这确实会导致运行时错误,但删除它并不能解决问题。

第二个问题是what已被宣布:

virtual const char* what() noexcept;

而它在std::exception宣布为:

virtual const char* what() const noexcept;

签名的这种差异意味着当它被std::exception的处理程序捕获时,它调用std::exception::what()而不是except::what()

值得一提的几点:

  1. 确保您的函数重载与基类中的函数完全匹配。
  2. 如果您希望抛出某种类型的异常,那么首先尝试使用特定的处理程序捕获该异常,并为了清楚起见使用适当的名称作为异常。
  3. 正如其他人所提到的,如果可以,请尝试使用std::string课程。它将使事情变得更容易和更安全。虽然在这种情况下,正如第二点所述,但字符串成员并不是必需的,因为该类具有足够的特定性,不需要进一步的限定。
  4. 不要创建异常类,除非它添加一些特定的值(尽管值,可能只是你想要特定地捕获某种类型的异常并以某种方式处理。)如果你想要一个更普遍的例外,那么std::runtime_error或在这种情况下,std::overflow_error将是不错的选择,并且都将std::string作为构造函数的参数,因此不需要创建自己的异常类。

例如:

#include <exception>
using namespace std;


class divide_by_zero : public std::exception
{
public:
    virtual const char* what() const noexcept { return "DIVIDED BY 0"; }
};

double div(const double& a, const double& b)
{
    if (b == 0.0)
        throw divide_by_zero();
    return a / b;
}

int main()
{
    try
    {
        std::cout << div(5.0, 0.0);
    }
    catch (divide_by_zero &ex)
    {
        std::cout << ex.what();
    }
    catch (std::exception &ex)
    {
        std::cout << ex.what();
    }
    return 0;
}

输出:

DIVIDED BY 0
© www.soinside.com 2019 - 2024. All rights reserved.