我在这里简化了我的问题,因为我有一个非常大的代码库而且我无法创建一个mcve。
我有一个可能会或可能不会成功构建的对象。如果没有,则在其构造函数
中抛出类型ObjectUnsupported
的异常
class Object {
public:
Object() {
read_data1();
..
if(unsupported_kind == true)
throw ObjectUnsupported();
..
read_data2();
}
std::vector<char> data1;
std::vector<char> data2;
};
data1
始终读取,而data2
仅适用于受支持的对象。
现在,我尝试使用智能指针
在其他地方构建对象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
总是在data2
不是,但这里的重点是:我可能需要data2
或者我可能不需要该对象
上面的代码不起作用,因为调用obj
智能指针的析构函数因此导致后续代码错误。
我如何实现目标?
答案 0 :(得分:2)
从构造函数中抛出异常不会给你留下半构造的对象。按照设计,该对象不存在。构建到例外点的所有成员都将被销毁。
这里的解决方案是让你的对象支持一个标志,指示它有多少数据。
例如:
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;
};