我有类似的东西:
#include "MyImage.hpp" // MyImage wraps the Qt library image class
namespace fs = boost::filesystem;
class ImageCollection {
public:
ImageCollection(const char* path);
private:
const fs::path path_;
deque<MyImage> instanceDeque_;
}
ImageCollection(const char* path) :
path_(fs::is_directory(path) ?
fs::complete(path) :
fs::complete(path).parent_path()) /* Can I even do this? */
{
/*** code in question ***/
fs::directory_iterator endIter;
for(fs::directory_iterator dirIter(path_); dirIter != endIter; dirIter++) {
instanceDeque_.push_back(MyImage(*dirIter));
}
}
当* dirIter是非图像文件的fs ::路径时,MyImage构造函数抛出MyInvalidFileException。
我希望MyImage和ImageCollection是不可变的。
我可以:
try {
instanceDeque_.push_back(MyImage(*dirIter));
}
catch(const MyInvalidFileException& e) { // oops, tnx Nemanja T.
// remember *dirIter in a list of non-Image files, to use later
continue;
}
投掷时会发生什么?在双端队列中是否留下了僵尸MyImage或僵尸元素?或者这实际上是正确的方法吗? (即中止push_back()并且不创建MyImage。)
我目前有一个凌乱的解决方法:
// load up an empty MyImage, which I'd rather not do
instanceDeque_.push_back(MyImage());
for(fs::directory_iterator dirIter(path_); dirIter != endIter; dirIter++) {
MyImage& attemptImage = instanceDeque_.back();
bool success = attemptImage.loadPath(*dirIter); // "fill" the empty MyImage
if (success)
instanceDeque_.push_back(MyImage()); // prepare another empty MyImage
}
instanceDeque_.pop_back(); // discard the empty MyImage
使用null QImage *初始化MyImage,loadPath()在堆上创建QImage。这迫使我到处都有空指针检查。我认为如果文件可以打开,应该有一种方法可以有一个QImage实例,如果文件不能打开则构造只是失败。
答案 0 :(得分:2)
这取决于MyImage
我猜。如果MyImage的构造函数中存在异常,则在您到达push_back
方法之前它应该失败。这是因为构造函数将在push_back
之前运行(这是合乎逻辑的,因为它需要一个值来传递方法)。因此,如果该步骤失败并抛出异常,则永远不会到达push_back
。
以下是一些提示:
答案 1 :(得分:1)
如果MyImage(*dirIter)
失败,您将无法进入push_back
,因此这不是问题。
答案 2 :(得分:1)
正如其他人已经提到的那样,如果MyImage
构造函数抛出,那么您将永远不会到达deque.push_back
函数,这样就不会有问题了。此外,如果它确实进入push_back
函数并且由于某种原因抛出它,那么你的双端队列对象将保持不变。如果操作失败,STL不允许方法修改/损坏容器。我找不到关于push_back
投掷documentation的任何内容,所以你可能不必担心,除非你的内存不足或其他极端情况。