C++ 自定义异常 类

C++ Custom Exception classes

我正在制作一个程序并决定自己做例外,所以我写了以下 header-only 文件:

#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

...
...

您是否尝试捕获 std::exception 而不是异常 class?

像这样:

try{
throw AAerr::Argument exception("Test");
} catch (std::exception exc) {
std::cout << "HEY" << std::endl;
}

我怀疑问题出在“主程序”中,请参阅其他答案中的 OP 评论:

yeah i tried and it's the same thing. it doesn't work on my main program, but works fine on the testing program i have – user898238409

如果“主程序”正在使用动态库并且异常被定义为“仅header”,这可能会导致为此[生成 RTTI(运行 时间类型信息)的情况=30=] 多次。动态库和主要可执行文件各包含一个,其中包含此 header 文件。

例如可以这样:

  1. 动态库在异常时使用为该库生成的 RTTI 创建 class AAerr::ArgumentException 的实例,并将其作为异常抛出。
  2. 主可执行文件正在尝试使用为该可执行文件构建的 RTTI 捕获该异常。

由于这两个 RTTI 彼此不匹配,因此 catch 语句无法注意到预期的异常被抛出。

正确的解决方法是删除“仅 header”异常,因此所有虚拟方法都应在 cpp 文件中定义。这将导致与特定库的明确关联。因此,ArgumentExceptionWrongReturnType.

将只有一个 RTTI。