Reputation: 309
I have read about exception safety and come to following question:
In class A m_value and m_data should be consistent with each other. But if
m_data = data;
throw class invariant will be broken.
class A
{
public:
void Set(const std::vector<unsigned int>& data)
{
m_value = ComputeValue(data);
m_data = data;
}
private:
int m_value; //That should be consistent with vector
std::vector<unsigned int> m_data;
}
Should I protect this code with some variant of copy and swap? Is it good decision to use copy and swap in every line of code like this or this code could be used as it is?
This is my solution, but I am not sure, should I use it or it is redundant complexity:
void Set(const std::vector<unsigned int>& data)
{
std::vector<unsigned int> tmp_data(data);
m_value = ComputeValue(tmp_data);
m_data.swap(tmp_data);
}
Append:
Another question: Should I write my own exception safe assigment operator or swap function to make it possible to use it like this:
class B
{
public:
SetA(const A& a)
{
A tmp_a(a);
m_a.swap(tmp_a);
}
private:
A m_a;
}
And in class A
void A::swap(A& rhs)
{
using std::swap;
swap(m_data, rhs.m_data);
swap(m_value, rhs.m_value);
}
Upvotes: 5
Views: 1046
Reputation: 1243
Using the copy-and-swap idiom is the easiest way to give your function the strong exception safety guarantee, if ComputeValue can throw. However, instead of passing by const reference and making a copy in the function, it's better to pass the vector by value, as this allows the compiler to call the move constructor if the function is passed an r-value.
void Set(std::vector<unsigned int> data)
{
m_value = ComputeValue(data);
m_data.swap(data);
}
If ComputeValue cannot throw, then all this hassle is not necessary and you can just assign the vector (passed by const reference) to the member variable before computing the new value.
Regarding your second question, I don't see any benefit over just assigning the function argument to the member variable, provided A's copy assigment operator provides the strong exception safety guarantee (which it should), which is also easy to achieve using the copy-and-swap idiom.
Upvotes: 2