C++ &引用;“未定义的符号”;从stdexcept类继承时
以下是C++ &引用;“未定义的符号”;从stdexcept类继承时,c++,debugging,inheritance,exception,C++,Debugging,Inheritance,Exception,以下是中定义的异常: 以下是我的例外: #include <string> #include <stdexcept> using namespace std; class rpn_expression_error : public logic_error { public: explicit rpn_expression_error(const string& __arg); }; 应@sbi的请求,下面是我目前代码的一个最小示例: #include
中定义的异常:
以下是我的例外:
#include <string>
#include <stdexcept>
using namespace std;
class rpn_expression_error : public logic_error
{
public:
explicit rpn_expression_error(const string& __arg);
};
应@sbi的请求,下面是我目前代码的一个最小示例:
#include <string>
#include <iostream>
#include <stdexcept>
using namespace std;
class RPN_Calculator {
public:
class rpn_expression_error : public logic_error {
public:
explicit rpn_expression_error(const string& arg) : logic_error(arg) {}
};
void Execute() {
throw rpn_expression_error("Hello");
}
};
int main() {
RPN_Calculator calc;
try {
calc.Execute();
} catch (exception e) {
cout << e.what() << endl;
}
}
#包括
#包括
#包括
使用名称空间std;
类RPN_计算器{
公众:
类rpn_表达式_错误:公共逻辑_错误{
公众:
显式rpn_表达式_错误(常量字符串和arg):逻辑_错误(arg){}
};
void Execute(){
抛出rpn_表达式_错误(“Hello”);
}
};
int main(){
RPN_计算器计算;
试一试{
计算执行();
}捕获(例外e){
Couth你捕捉异常的方式有问题。具体地,考虑这个代码:
struct Base
{
virtual void do() { std::cout << "Base!" << std::endl; }
};
struct Derived : Base
{
virtual void do() { std::cout << "Derived!" << std::endl; }
};
void foo(Base x)
{
x.do();
}
int main()
{
Derived d;
foo(d); // <--
}
我们上面的代码将显示“派生!”,因为它不再被切片(也可以使用指针)
那么,看看你的条款:
catch (exception e)
在这里,您抛出的任何异常都将被分割到基本的std::exception
类中,从而丢失任何派生信息!这就是为什么通过引用捕获更为常见(并且可能“正确”)的原因:
catch (const exception& e)
现在您将找到e.what()
按预期返回非切片错误消息
古老的
下面是整个内容的外观(不要在标题中使用名称空间):
请记住,我已更改了您的参数名称。包含双下划线的名称是保留的,您不应该使用它们。看起来您已经声明了构造函数,但没有提供构造函数的定义。它说函数未定义,因为您忘了定义它。请尝试以下操作:
#include <string>
#include <stdexcept>
using namespace std;
class rpn_expression_error : public logic_error
{
public:
explicit rpn_expression_error(const string& arg)
: logic_error( arg ) { } // definition
};
另外,除非您的RPN表达式都是硬编码的,否则它们中的错误将是运行时错误
s,而不是逻辑错误
s。如果这是您的代码,那么问题是(正如我建议的,Adrian也说过的)您已为rpn\u expression\u error
类声明了构造函数,但尚未定义它。请尝试将其添加到代码中(在类声明下方):
虽然我确实忘记了#包括;
(doh!),我是使用名称空间std;
。我添加了#include
,什么都没有。我添加了std::
,什么都没有。我去掉了双下划线,什么都没有。@Austin:好吧,我想是时候发布一段复制错误的最小代码了,我们可以将它粘贴到我们的编辑器中,然后自己尝试一下。@Austin:不要不要在头文件中使用名称空间std;
,你会从中得到各种各样的麻烦。(可能永远不会,但这更值得商榷。)我将编辑我的答案,以展示你应该如何完整地完成这件事。但正如sbi所说,我们需要更多的代码来确保。(哎哟,否决票:P)谢谢你提供的使用名称空间std
的提示。我不知道。@Austin:没问题。也许我很傻,但是问题解决了吗?你上面给出的代码(完整代码)不应该有任何更改以使其成为全局范围。(也就是说,它应该可以正常工作,因为我刚刚在答案中添加了更改。)愚蠢的问题,你曾经在源文件中定义过rpn\u expression\u error
构造函数吗?你确定要将定义限定为rpn\u expression\u error::rpn\u expression\u error
?并且相应的对象文件是否链接到你的可执行文件中?如果一个或多个ose不是真的。感谢您关于运行时与逻辑错误的说明。我阅读文档的方式,听起来像是logic\u error
代表了一些与人为错误有关的内容,而runtime\u error
代表了一些与技术错误有关的内容。
catch (exception e)
catch (const exception& e)
// rpn_expression_error.h
#include <stdexcept> // for logic_error
#include <string> // for string
class rpn_expression_error : public std::logic_error
{
public:
explicit rpn_expression_error(const std::string& pMsg);
};
// rpn_expression_error.cpp
#include "rpn_expression_error.h"
rpn_expression_error::rpn_expression_error(const std::string& pMsg) :
std::logic_error(pMsg)
{}
#include <string>
// ...
vvv
explicit rpn_expression_error(const std::string& arg);
#include <string>
#include <stdexcept>
using namespace std;
class rpn_expression_error : public logic_error
{
public:
explicit rpn_expression_error(const string& arg)
: logic_error( arg ) { } // definition
};
#include <string>
#include <stdexcept>
class rpn_expression_error : public std::logic_error
{
public:
explicit rpn_expression_error(const std::string& arg)
: logic_error( arg ) { } // definition
};
rpn_expression_error::rpn_expression_error(const string& arg)
: logic_error(arg)
{
}