我希望能够抛出一个构造对象,但在抛出之前对其进行修改 (使用Named Parameter Idiom)。 考虑:抛出的对象复制构造 - 为什么?
#include <iostream>
#include <exception>
using namespace std;
struct my_exception : std::exception {
my_exception() {
cout << "my_exception(): this=" << hex << (unsigned long)this << endl;
}
my_exception(my_exception const&) {
cout << "my_exception(my_exception const&)" << endl;
}
~my_exception() throw() {
cout << "~my_exception()" << endl;
}
my_exception& tweak() {
return *this;
}
char const* what() const throw() { return "my_exception"; }
};
int main() {
try {
throw my_exception().tweak();
}
catch (my_exception const &e) {
cout << "&e=" << hex << (unsigned long)&e << endl;
}
}
当我运行程序时,我得到:
my_exception(): this=7fff5fbfeae0
my_exception(my_exception const&)
~my_exception()
&e=1001000f0
~my_exception()
正如你所看到的,捕捉到的异常对象不是唯一的最初抛出的一个。 如果我删除调用tweak()
,我反而得到:
my_exception(): this=1001000f0
&e=1001000f0
~my_exception()
对于那些tweak()
叫的话,为什么被称为拷贝构造函数?我想要tweak()
在最初构建的对象上进行操作,并且不需要复制。有什么办法可以防止复制结构?
仅供参考:我使用g ++ 4.2.1(Mac OS X上的Xcode的一部分)。
那么,如何修改我的示例以使用clone()和/或虚拟rethrower方法? – 2011-03-22 06:26:33
@保罗:我不会。但是,当我写这篇文章时,你并没有解释你的“调整”方法是什么意思。对此猜测,它意味着要做一些额外的初始化,一个好的方法是改为定义派生类并在'throw'语句中使用该类。干杯&hth。, – 2011-03-22 06:29:38
不明白需要虚拟重新投掷者。如果你通过引用来捕获并使用'throw;'重新抛出,那么一旦实现抛出异常,将不会有更多的副本。 – 2011-03-22 07:27:31