在一次采访中,有人问我为什么按值捕获异常可能是个问题,我回答说这会导致对象切片。这就是我在互联网上找到的,例如这里:https ://www.viva64.com/en/w/v746/
但是现在我正在尝试进行实验,并且在按值捕获时找不到切片的示例。切片的通常场景(没有例外)是这样的:
Derived d1;
Derived d2;
Base& b1 = d1;
Base& b2 = d2;
b1 = b2;
在最后一行调用 Base 的赋值运算符,它只复制 Derived 对象的 Base 部分。因此,b1 的基于部分是从 d2 复制的,而 b1 的派生部分仍然来自 d2。坏的。
但是当按值捕获异常时怎么会发生这种情况呢?
我尝试了这段代码(同时使用:g++ 和 Sun CC 编译器):
struct Base
{
virtual void print() const
{
cout << "{ Base: " << m << " }" << endl;
}
Base(int _m = 0) : m(_m) {}
int m;
};
struct Derived : Base
{
Derived(int _m = 0, int _n = 0) : Base(_m), n(_n) {}
void print() const
{
cout << "{ Base: " << m << ", Derived: " << n << " }" << endl;
}
int n;
};
int main()
{
try
{
try
{
throw Derived(3, 300);
}
catch(Base x)
{
cout << "Inner catch: ";
x.print();
throw;
}
}
catch(Derived y)
{
cout << "Outer catch: ";
y.print();
}
}
输出是:
Inner catch: { Base: 3 }
Outer catch: { Base: 3, Derived: 300 }
所以我抛出 Derived 异常,捕获它的 Base BY VALUE 并重新抛出,然后捕获 Derived BY VALUE 并且一切正常,没有任何切片。那个怎么样?
有人可以提供一个按值捕获时切片的例子吗?