【发布时间】:2021-08-24 15:53:00
【问题描述】:
我正在制作一个程序,并决定创建自己的例外,所以我编写了以下仅头文件:
#ifndef ARGUMENT_EXCEPTIONS
#define ARGUMENT_EXCEPTIONS
#include <exception>
namespace AAerr {
class ArgumentException : public std::exception {
private:
const char* msg;
static constexpr char* funcName = (char*)"ArgumentException";
public:
ArgumentException(const char* msg_) {
msg = msg_;
}
const char* getMessage() {
return msg;
}
virtual const char* what() const throw() {
return funcName;
}
};
class WrongReturnType : public ArgumentException {
private:
const char* msg = "Wrong Type";
char requestedType;
char ofType;
static constexpr char* funcName = (char*)"WrongReturnType";
public:
WrongReturnType(const char requested, const char is) : ArgumentException(msg) {
requestedType = requested;
ofType = is;
}
char get_requested_type() {
return requestedType;
}
char get_of_type() {
return ofType;
}
virtual const char* what() {
return funcName;
}
};
}
#endif // ARGUMENT_EXCEPTIONS
当我试图在我的程序中抛出并捕捉其中一个时,它从未捕捉到任何东西:
#include "exception_header_file.hpp" // the name of the header file
#include <iostream>
int main() {
try {
throw AAerr::ArgumentException("TEST");
} catch (AAerr::ArgumentException& exc) {
std::cout << "CAUGHT EXCEPTION" << std::endl; // never executed
}
}
然后我制作了第二个文件(只是为了找出问题所在):
#include <iostream>
#include <exception>
namespace AAerr {
class Exc : public std::exception {
private:
const char* msg;
static constexpr char* funcName = (char*)"TEST FUNC";
public:
Exc(const char* msg_) {
msg = msg_;
}
const char* getMessage() {
return msg;
}
virtual const char* what() {
return funcName;
}
};
class Exc2 : public Exc {
private:
int line;
static constexpr char* funcName = (char*)"FUNCTION";
public:
Exc2(const char* msg_, int line_) : Exc(msg_) {line = line_;}
virtual const char* what() {
return funcName;
}
};
};
int main() {
try {
throw Exc2("TEST", 5);
} catch (AAerr::Exc& exc) {
std::cout << "CAUGHT EXCEPTION" << std::endl; // works fine
}
}
谁能帮我找出问题所在??我找不到这两个之间的任何区别。
编译器:g++(gcc) 平台:ubuntu(linux)
编辑: 我设法解决了这个问题。
它在链接器(ld)上。
我更改了我的 Makefile 来构建整个项目,而不是先制作然后链接所有内容。
我的意思是,我做到了:
build:
g++ program_part1.cpp program_part2.cpp program_part3.cpp -o example.elf
代替:
build: part1.o part2.o part3.o
g++ part1.o part2.o part3.o -o output.elf
part1.o: program_part1.cpp program_part1.hpp
g++ -c program_part1.cpp -o part1.o
...
...
【问题讨论】:
-
对于使用 RTTI 的事物(捕获异常正在使用它),不要使用仅标头类更安全。使用动态库时可能会出现问题(您的问题没有描述)。
-
您的代码按预期工作,尽管您在初始化之前使用了成员变量
msg。 godbolt.org/z/T8xqqqcsz -
不确定这是否会导致问题,但是:
msg = msg_;对初始化字符串成员变量是否正确?看起来ArgumentException和WrongReturnType实际上在他们的what方法上有不同的签名,我不确定这是多么刻意。