I need to check if thrown exception from operator=?


I need to check if thrown exception from operator=?



Given the following code:


template <class T>
class A {
T* arr;
int size;
public:
A(int size) : arr(new T[size]) , size(size) {
}
//..

A& operator=(const A& a){
if(this == &a){
return *this;
}
this->size = a.size;
T* ar=new T[a.size];
for(int i=0 ; i<size ; i++){
ar[i]=a.arr[i]; // I need to do it at "try-catch" ?
}
delete this->arr;
this->arr=ar;
return *this;
}
//...
};



When I copy the elements from the given array, do I need to do it with a try-catch clause or not? is it a good idea or not?


try-catch





Aren't there some guarantees about "assignment [should] never throw(s)" in [a valid program in] C++?
– user2864740
Jun 30 at 20:18






@user2864740 No. Some types might provide such a guarantee, some types might not.
– Barry
Jun 30 at 20:20





@Software_t - So in arr[i]=a.arr[i]; you use T::operator=(const T&). Could that throw? Well - Yes.
– Bo Persson
Jun 30 at 20:34


arr[i]=a.arr[i];


T::operator=(const T&)





@Software_t - Yes. Or add restrictions on T. If it is an int, for example, there will be no problem. That was what my first comment was supposed to be about. :-)
– Bo Persson
Jun 30 at 20:53



T


int





I think you should not modify the size field of A so early. If the array alloc or T copy does exception, then the A object will be invalid, as its size does not match its allocation.
– Gem Taylor
2 days ago




1 Answer
1



I can see that potentially your T copy could throw due to its own alloc failure or other reasons.
On the other hand your A copy could already throw because it had alloc failure.



Currently you would need to handle the destruction because you have not concreted the array that you have allocated, and all the T instances that you have created need to be destroyed if one of them exceptions, perhaps due to allocation failure.



One quick way to fix that would be to hold the array in a unique_ptr. Then it will be destroyed on exiting context.



Another way may be to reconsider your contract on A after the assignment has exceptioned: It must be valid, i.e. survive being used, but perhaps it need not guarantee to still contain its previous contents, nor all the new contents, so you could decide to destroy its existing array before allocating and assigning a new array, then copying the members. You could decide not to reallocate if the size has not changed, but just re-assign - this would leave a mess of new and old members after an exception, but they would all be valid and safe to delete.



Please ensure that size matches the actual attached array size at all times! Your existing code makes this mistake, but in particular that it is set to null and 0 after the delete and before the assignment; and it is only set to new new size after the assignment of the new pointer.






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

How to input without newline? (Python)

C++ thread error: no type named ‘type’ MINGW

Analog for TagView in flutter