我想弄清楚我抛出的对象存储在内存中的位置.所以我为它写了一个小程序:
#include <iostream>
#define print_dist() int a;\
do { std::cout << __FUNCTION__ << "() a[" << (long)&a - (long)ptrMainStackBase << "]" << std::endl; } while (0)
#define print_distx(x) \
do { std::cout << __FUNCTION__ << "() " #x "[" << (long)&x - (long)ptrMainStackBase << "]" << std::endl; } while (0)
#define print_distxy(x, y) \
do { std::cout << __FUNCTION__ << "() " #x "(ex)[" << (long)&x - (long)y << "]" << std::endl; } while (0)
class CTest
{
public:
CTest()
{ std::cout << "CTest::CTest" << std::endl; }
// private:
CTest(const CTest&)
{ std::cout << "copy" << std::endl; }
};
const CTest *ptrException;
int *ptrMainStackBase;
void Test2()
{
print_dist();
CTest test;
print_distx(test);
std::cout << "&test=" << &test << std::endl;
throw test;
}
void Test1()
{
print_dist();
try
{
Test2();
}
catch (const CTest& test)
{
ptrException = &test;
print_dist();
print_distx(test);
print_distxy(test, ptrException);
std::cout << "&test=" << &test << std::endl;
throw test;
}
}
int main()
{
int b;
ptrMainStackBase = &b;
print_dist();
try
{
print_dist();
Test1();
}
catch (const CTest& test)
{
print_dist();
print_distx(test);
print_distxy(test, ptrException);
std::cout << "&test=" << &test << std::endl;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它打印:
main() a[-4]
main() a[-8]
Test1() a[-64]
Test2() a[-104]
CTest::CTest
Test2() test[-108]
&test=0x7fffd3b21628 <- test created here on stack
copy
Test1() a[-68]
Test1() test[-140736732956164]
Test1() test(ex)[0]
&test=0xb89090 <- and copied here
copy
main() a[-12]
main() test[-140736732956020]
main() test(ex)[144]
&test=0xb89120 <- and here
Run Code Online (Sandbox Code Playgroud)
看起来,当我抛出一个对象时,它首先被复制到另一个远离正常对象的堆栈.这是真的?为什么两个"异常堆栈帧"之间有144字节的距离?
当你抛出一个对象时,它确实首先被复制到一个临时位置.否则,展开堆栈会使其超出范围.然后通过引用捕获它会导致未定义的行为,如下所示:
void foo() {
A a;
throw a;
}
void bar() {
try {
foo();
} catch (A& a) {
// use a
}
}
Run Code Online (Sandbox Code Playgroud)
除非a被复制到某个临时位置,否则您将引用一个不再存在的变量catch.要使其工作,A必须有一个公共拷贝构造函数(除非你使用VS,在这种情况下它也将使用私有...).此外,这是通过引用捕获的一个很好的理由 - 否则,您将有两个复制结构而不是一个.
| 归档时间: |
|
| 查看次数: |
158 次 |
| 最近记录: |