【发布时间】:2022-01-22 14:39:56
【问题描述】:
所以我正在为我正在编写的程序设置自定义异常类。我正在创建一个包罗万象的基类,我将主要将其用作通用异常。这个基类将被其他几个自定义异常继承。这是基类和附加异常类之一,将有 10+ 个子类从父类继承。
#include <exception>
#include <string>
#include <string.h>
class AgentException : public std::exception
{
protected:
char *msg;
public:
AgentException() : msg("AgentException"){};
AgentException(char *m) : msg(m){};
AgentException(char *m, std::string d)
{
strcat(m, d.c_str()); //aware this fails. its a segmentation fault
};
~AgentException() = default;
const char *what() const throw()
{
return (const char *)msg;
}
};
class ConnectionFailed : public AgentException
{
private:
std::string eType = "ConnectionFailed";
public:
ConnectionFailed() : AgentException("ConnectionFailed"){};
ConnectionFailed(std::string d) : AgentException("ConnectionFailed: ", d){};
~ConnectionFailed() = default;
};
我知道上面的代码 what() 目前不会返回任何东西,因为没有分配成员变量。我忽略了它,因为我从 strcat() 调用中遇到了分段错误。
我为父类创建了多个构造函数,因为有时我希望传递默认值、单个值甚至两个参数。对于子类,它总是至少将类 ID 传递给父类,在某些情况下,我可能需要将字符串变量与类 id 一起传递。字符串变量 std::string 是必须的。这些是我被赋予使用的指令。
最初我在类中将所有消息变量设置为 std::string,但我最终遇到了与 what() 函数相关的问题。我不知道如何将std::string 转换为const char*。在做了一些研究之后,我发现在异常类中使用字符串是一个坏主意,因为什么会捕获可能发生在其中的任何异常
所以我将所有内容都转换回const char*,但现在我似乎无法从what() 获得返回。这些问题都源于我无法弄清楚不同类型的串联。
通过对 AgentException 类的这种更改,我可以得到一些可以正常工作的东西。
protected:
char msg[100];
public:
// AgentException() : msg("AgentException"){};
// AgentException(char *m) : msg(m){};
AgentException(const char *m, std::string d)
{
strcpy(msg, m);
strcat(msg, d.c_str());
};
我可以让这种改变整体发挥作用,但感觉这不是正确的做法。有人可以告诉我他们将对此设置进行的更改吗?
我目前正在通过抛出 AgentException 或 ConnectionFailed 异常并使用 Base AgentException 捕获来进行测试。我一直在旋转,看看是否有任何不同的反应。
try
{
throw ConnectionFailed("test");
}
catch (const AgentException &e)
{
std::cout << "----------------" << std::endl;
std::cerr << e.what() << '\n';
std::cout << "_________________" << std::endl;
}
【问题讨论】:
-
AgentException(char *m, std::string d)不会初始化从what返回的成员,从而导致第一个替代方案中的未定义行为。此外,您是否正在编写 C++11 之前的代码?否则what的签名应该是const char* what() const noexcept;,您可以添加override让编译器检查签名是否与基类中的签名匹配。 -
@fabian 我在第一部分代码中指出它当前正在引发异常。我没有将它分配给成员,因为 strcat 不起作用。我可以通过在代码的第二部分进行更改来使其工作。
-
您是否有机会按价值捕获异常?您是否有理由不从
std::runtime_error派生并让它处理存储what消息? -
@AlanBirtles 所以我更新了我的帖子,向您展示我用来测试异常的代码部分。关于不是从 std::runtime_error 派生的,我没有答案。我会再读一读。它是否使用 what 消息管理多个参数?
-
它从
what返回,无论你在构造函数中传递什么,你仍然需要连接字符串来构建该消息,但你可以使用std::string来做到这一点
标签: c++ exception concatenation stdstring const-char