我正在处理一个请求用户输入文件,用户名和密码的对话框。我希望在选择问题时通知用户。在我查看对话框的名称和密码字段之前,该文件必须有效。我知道还有其他方法可以做到这一点,我的问题是关于这个过程的效率。
我的MFC C ++应用程序有一个字符串表,其中使用宏将字符串标识为将整数(#define IDS_SOME_ERROR 100
)映射到整数(throw
),其中这些整数可以由MFC框架用于从中加载字符串字符串表。
我对投掷原始类型的效率感到好奇,因此我查看了cpprefrence.com上的throw expression
关键字。
int
语句从表达式复制初始化异常对象(这可以调用rvalue表达式的移动构造函数,复制/移动可能受复制省略),然后将控制转移到异常处理程序最近输入的复合语句或成员初始值设定项列表的匹配类型,不会被此执行线程退出。即使复制初始化选择了移动构造函数,从lvalue复制初始化也必须格式正确,并且析构函数必须是可访问的(从C ++ 14开始)。
以下是another question询问要投掷的类型,我注意到一条评论说不要抛出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
由于throw
是C ++中的原始类型,catch
语句是否仍然必须执行任何复制?以这种方式在C ++中抛出原始类型是否安全?删除catch块并将我的错误对话逻辑从{{1}}块放到每个抛出位置会更有效吗?如果我这样做,我还必须嵌套我的代码,这样如果有多个错误,只显示一个对话框。
答案 0 :(得分:2)
您不应过分担心效率,因为建议捕获std::exeption
个派生词的做法是使用const
引用。
它的优点是引入了一个异常层次结构,并使用const char* std::exception::what() const
提供了重写的错误消息。
答案 1 :(得分:0)
我想说做这样的事情会更好,而不是抛出内置类型:
struct SomeError{int errid};
...
throw SomeError{IDS_BAD_FILE};
答案 2 :(得分:0)
让我们从正确的术语开始吧。 C ++没有基本类型的概念。在C ++中,有内置类型和自定义类型。
对于这个问题, int
是一种内置类型。虽然从语言的角度来看,抛出int
类型的对象与抛出MySpecialClass
类型的对象或std::exception
的派生没什么不同,抛出后者有一个好处 - 因为这是一个众所周知的例外,人们可能会认为程序中某处会有catch (const std::exception& e)
。此catch将处理std::exception
的所有派生,并且至少可以在异常中打印消息。
然而,期望一个人赶上int
是不合理的!即使一个人做了,接下来呢?应如何处理此异常?打印到控制台的号码?用户应该做些什么呢?