Bel*_*loc 5 c++ exception-handling visual-studio-2008 object-slicing
块中的new表达式在我的计算机中try引发bad_alloc异常.
请注意,catch子句按值接收异常对象,而不是通过引用.e.what()打印"bad allocation"怎么样?我以为会被切成碎片.
#include <iostream>
int main()
{
try
{
int* p = new int[0x1F000000];
}
catch(std::exception e)
{
std::cout << e.what() << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
GMa*_*ckG 13
Visual Studio(Dinkumware?)使用std::exception包含内部存储†的实现来实现消息.(使用接受字符串的非标准构造函数完成.)
因此,实际上不需要虚拟调度来获取错误消息,它可以在任何切片中存活.
更正统的实现确实会打印一个通用的异常消息,因为派生的对象被切掉了.(实际上,MS已经制作std::exception并且std::runtime_error等效.这没有任何问题,因为返回值std::exception::what是实现定义的,但它解释了你的结果.)
†此处的内部存储空间松散.它没有内部缓冲区,但它有a const char*和a bool.const char*消息的指向(返回值what()),bool是一个确定是否应删除缓冲区的标志.
就像这样:
class msvc_exception // for exposition
{
public:
msvc_exception(const char* msg) :
mMsg(msg),
mDoDelete(false)
{}
msvc_exception(const std::string& msg) :
mMsg(copy_string(msg)),
mDoDelete(true)
{}
virtual ~msvc_exception()
{
if (mDoDelete)
delete [] mMsg;
}
virtual const char* what() const throw()
{
return mMsg ? mMsg : "unknown";
}
private:
const char* copy_string(const std::string& str)
{
const char* result = new char[str.size() + 1];
std::copy(str.begin(), str.end(), result);
result[str.size()] = 0; // null-terminate
return result;
}
};
Run Code Online (Sandbox Code Playgroud)
你现在看到的bad_alloc是这样的:
class msvc_bad_alloc : // for exposition
public msvc_exception
{
public:
msvc_bad_alloc() :
msvc_exception("bad_alloc") // note: a static string, no dynamic storage
{}
};
Run Code Online (Sandbox Code Playgroud)
切片不会影响消息,因为基类中的消息"存在".
其他编译器,如GCC和LLVM,更直接地实现它:
class orthodox_exception
{
public:
orthodox_exception(){}
virtual ~orthodox_exception() {}
virtual const char* what() const throw()
{
return "orthodox_exception";
}
};
class orthodox_bad_alloc :
public orthodox_exception
{
public:
const char* what() const throw()
{
return "orthodox_bad_alloc";
}
};
Run Code Online (Sandbox Code Playgroud)
在这里,切片会影响你的结果.(也就是说,毕竟:总是通过引用来抓住.)
| 归档时间: |
|
| 查看次数: |
3152 次 |
| 最近记录: |