Reputation: 6960
I'm simplifying my problem here since I have a pretty large codebase and I can't make a mcve.
I have an object which might or might not be constructed successfully. If not, an exception of kind ObjectUnsupported
is thrown in its constructor
class Object {
public:
Object() {
read_data1();
..
if(unsupported_kind == true)
throw ObjectUnsupported();
..
read_data2();
}
std::vector<char> data1;
std::vector<char> data2;
};
data1
is always read while data2
is only available for supported objects.
Now, I'm trying to construct an object somewhere else by using a smart pointer
std::unique_ptr<Object> obj;
try {
obj = std::make_unique<Object>();
} catch(ObjectUnsupported& ex) {
object_is_unsupported = true;
}
if(object_is_unsupported) {
if(checkIfDataIsNeeded(obj->data1) == false)
return; // We didn't need it anyway
else
throw RuntimeError(); // Data was needed! Abort!
}
data1
is always read while data2
is not but the point here is: I might need that data2
or I might not need the object at all.
The code above doesn't work since the destructor for the obj
smart pointer is called therefore rendering my subsequent code wrong.
How can I achieve my goal?
Upvotes: 2
Views: 68
Reputation: 69882
Throwing an exception from a constructor does not leave you with a half-constructed object. By design, that object does not exist. All the members that were constructed up till the point of the exception will be destroyed.
The solution here is for your object to support a flag that indicates how much data it has.
for example:
class Object {
public:
Object() {
read_data1();
..
if(!unsupported_kind)
{
read_data2();
_has_supported_data = true;
}
}
bool has_supported_data() const {
return _has_supported_data;
}
std::vector<char> data1;
std::vector<char> data2;
private:
bool _has_supported_data = false;
};
Upvotes: 2