在C++中引发基元类型
Throwing primitive types in C++
我正在处理一个对话框,该对话框向用户请求文件、用户名和密码。我希望用户在选择出现问题时得到通知。在检查对话框的名称和密码字段之前,文件必须是有效的。我知道还有其他方法可以做到这一点,我的问题是这个过程的效率。
我的MFC C++应用程序有一个字符串表,其中使用将转换单元映射到整数(#define IDS_SOME_ERROR 100
)的宏来标识字符串,其中MFC框架可以使用这些整数从字符串表加载字符串。
我对抛出基元类型的效率很好奇,所以我研究了cpprrefence.com.上的throw
关键字
throw expression
语句副本从表达式初始化异常对象(这可能会调用右值表达式的move构造函数,并且副本/移动可能会受到副本省略),然后将控制权转移到具有匹配类型的异常处理程序,该异常处理程序的复合语句或成员初始值设定项列表最近被此执行线程输入而未退出。即使复制初始化选择了移动构造函数,从左值进行的复制初始化也必须格式正确,并且析构函数必须是可访问的(因为C++14)。
这是另一个关于抛出类型的问题,我注意到一条评论说不要抛出int
或string
之类的东西。为什么会这样?
这是我的代码:
void SomeDialog::OnOK()
{
UpdateData();
try
{
if (VerifySomeFile(myFileStruct.getPath()))
{
if (DialogNameField.IsEmpty())
{
throw IDS_ERROR_NOID; // "No name specified."
}
if (DialogPasswordField.IsEmpty())
{
throw IDS_ERROR_NOPWD; // "No password specified."
}
CDialog::OnOK();
}
else
{
throw IDS_BAD_FILE; // "Bad or expired file."
}
}
catch (int errIDS)
{
CString tempStr;
tempStr.LoadString(errIDS);
AfxMessageBox(tempStr, MB_OK);
}
}
既然int
是C++中的基元类型,那么throw
语句还需要执行任何复制吗?以这种方式在C++中抛出基元类型安全吗?移除catch块并将我的错误对话框逻辑从catch
块放置到每个抛出位置会更有效吗?如果我要这样做,我还必须嵌套我的代码,以便在出现多个错误时只显示一个对话框。
您不应该过于担心的效率,因为捕获std::exeption
衍生物的推荐做法是无论如何使用const
引用。
它的优点是引入了异常层次结构,并使用const char* std::exception::what() const
提供重写的错误消息。
我认为这样做会更好,而不是抛出内置类型:
struct SomeError{int errid};
...
throw SomeError{IDS_BAD_FILE};
让我们从正确使用术语开始。C++没有基元类型的概念。在C++中,有内置类型和自定义类型。
就这点而言,int
是一个内置类型。虽然从语言的角度来看,抛出int
类型的对象与抛出MySpecialClass
类型的对象或std::exception
的派生对象没有什么不同,但抛出后者有一个好处——因为这是一个众所周知的例外,人们可能会认为程序中的某个位置会有catch (const std::exception& e)
。这个catch将处理std::exception
的所有派生,并且至少可以在异常中打印消息。
然而,期望一个人赶上int
是不合理的!即使这样,下一步会怎样?应该如何处理此异常?打印到控制台的数字?用户应该如何看待它?
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 模板元程序查找相似的连续类型名称
- 是否可以从int转换为enum类类型
- 构造函数正在调用一个使用当前类类型的函数
- 我应该使用什么来代替void作为变体中的替代类型之一
- 类中的字符串不命名类型