【发布时间】:2020-05-02 04:39:40
【问题描述】:
我面临以下问题。在文件 my_exception.h 中,我定义了自己的异常类,继承自 std::exception:
// File "my_exception.h"
#include <exception>
#include <string>
namespace proj { namespace exception {
struct Exception : public std::exception {
explicit Exception(const std::string& msg) noexcept : msg_(msg) { }
inline const char* what() const noexcept override { return msg_.c_str(); }
private:
std::string msg_;
};
} }
然后我在另一个命名空间中定义了一个名为BadParameterAccess 的派生异常类,将声明和实现分别拆分在 .h 和 .cpp 文件中:
// File parameter_exception.h
#include "exception.h"
namespace proj { namespace parameter {
struct BadParameterAccess final : public exception::Exception
{
BadParameterAccess() noexcept;
};
} }
// File parameter_exception.cpp
#include "parameter_exception.h"
namespace proj { namespace parameter {
BadParameterAccess::BadParameterAccess() noexcept
: exception::Exception("[BadParameterAccess] parameter not set yet."){ }
} }
我尝试使用多个编译器编译此代码。 使用 clang 6.0 我收到以下错误:
parameter_exception.cpp:7:18: error: initializer 'Exception' does not name a non-static data member or base class; did you mean the base class 'Exception'?
: exception::Exception("[BadParameterAccess] parameter not set yet."){ }
^~~~~~~~~
Exception
./parameter_exception.h:11:35: note: base class 'exception::Exception' specified here
struct BadParameterAccess final : public exception::Exception
^~~~~~~~~~~~~~~~~~~~~~~~~~~
g++ 7 给出等效错误,Visual Studio 2017 给出以下错误:
parameter_exception.cpp(8): error C2039: 'Exception': is not a member of 'std::exception'
代码在以下情况下完美编译:
- 在文件 parameter_exception.cpp 我指定了基类初始化程序的完整路径 (
proj::exception::Exception),或者 - 在文件 parameter_exception.cpp 我从基类初始化程序 (
Exception) 中删除命名空间,或者 - 在文件 my_exception.h 我删除了来自
std::exception的继承,或者 - 我以其他方式重命名我的命名空间
exception。
据我从我得到的不同错误中了解到,编译器希望在 std::exception 类内而不是在命名空间 exception 内找到一个名为 Exception 的成员,但我不明白为什么会这样发生。
此外,当我首先从头文件 parameter_exception.h 中的exception::Exception 继承时,我希望编译器会给我一个错误,但事实并非如此。
谁能解释一下原因?
提前谢谢你。
【问题讨论】:
-
我认为从
std::exception派生的名称exception(不合格)进入Exception的范围,但我不知道在哪里查看此规则的标准。 -
你使用struct而不是class有什么原因吗?
-
@anastaciu 不是特别是,但我看不出使用类而不是结构的原因。
-
可能是您没有#included 异常标头吗?
#include <exception>和#include "exception.h"都将包含 std::exception -
@jiveturkey 不,我已经包含了正确的,否则当我指定
Exception类的全名时它不会编译。
标签: c++ inheritance namespaces