代码之家  ›  专栏  ›  技术社区  ›  Kache

如何构造MyClass的容器,MyClass构造函数可以在其中抛出?

  •  2
  • Kache  · 技术社区  · 15 年前

    我有点像:

    #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;
    }
    

    当它抛出时会发生什么?Deque中是否还有僵尸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
    

    其中myImage初始化为空的qImage*,loadPath()在堆上创建一个qImage。这迫使我到处都有空指针检查。我认为如果文件可以打开,应该有一个qimage实例,如果文件不能打开,构造就会失败。

    3 回复  |  直到 15 年前
        1
  •  2
  •   Skurmedel    15 年前

    这取决于 MyImage 我猜。如果myimage的构造函数中存在异常,那么它应该在到达 push_back 方法。这是因为构造函数将在 推挽 (这是合乎逻辑的,因为它需要一个值来传递方法)。因此,如果该步骤失败并引发异常, 推挽 永远无法联系到。

    以下是一些提示:

        2
  •  1
  •   Andreas Brinck    15 年前

    如果 MyImage(*dirIter) 失败,你不会进入 push_back 所以这不是问题。

        3
  •  1
  •   cchampion    15 年前

    正如其他人已经提到的,如果 MyImage 构造函数抛出,则永远无法到达 deque.push_back 这样就不会有问题了。如果它真的进入 push_back 函数,它出于某种原因抛出,那么deque对象将保持不变。如果操作失败,STL不允许方法修改/损坏容器。我什么都找不到 推挽 投入 documentation 所以你可能不必担心,除非你的记忆力不足或者其他极端情况。