我有一个设计问题。让我们首先说这段代码
struct Trial{
const double a;
Trial(double a_) : a(a_){}
};
int main(){
Trial t1(1.);
Trial t2(2.);
t1 = t2;
}
不编译,因为Trial::operator=
默认情况下不是编译器构建的,因为Trial::a
is const
. 这很明显。
现在的重点是,代码优先
struct Trial{
const double a;
Trial(double a_) : a(a_){}
};
struct MyClass : private Trial{
MyClass(double a_) : Trial(a_), i(0) {};
void wannaBeStrongGuaranteeMemberFunction(){
MyClass old(i);
bool failed = true;
//... try to perform operations here
if(failed)
*this = old;
}
unsigned int i;
};
int main(){
MyClass m1(1.);
m1.wannaBeStrongGuaranteeMemberFunction();
}
我需要为类的某些方法提供强大的异常安全性,这些方法派生自Trial
. 此类方法对无穷无尽的一系列成员(在示例中)执行无穷无尽的一系列操作i
,这使得“手动”恢复操作变得不切实际。因此,我决定最好复制整个课程并在任何失败时将其复制回来。
小括号,代码只是一个例子。遗留的真实世界代码中的一切都复杂得多。在这个例子中,复制就i
可以了,但在实际代码中并非如此。此外,这些操作有多个(和复杂的)执行路径,因此将它们“读取”为“事务”会很痛苦。此外,我正在使用范围保护来实现这一点,因此可以在真实代码中正确管理异常。
当然整个事情都没有编译,因为*this = old
.
您将如何解决问题/解决问题?