如何构造MyClass的容器,MyClass构造函数可以抛出哪个容器?

时间:2009-12-18 15:17:19

标签: c++ exception constructor

我有类似的东西:

#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实例,如果文件不能打开则构造只是失败。

3 个答案:

答案 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的任何内容,所以你可能不必担心,除非你的内存不足或其他极端情况。