Как построить контейнер MyClass, куда может закинуть конструктор MyClass? - PullRequest
2 голосов
/ 18 декабря 2009

У меня есть что-то вроде:

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

Конструктор MyImage создает исключение MyInvalidFileException, когда * dirIter представляет собой путь fs :: к файлу, не являющемуся изображением.

Я бы хотел, чтобы 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

Где MyImage инициализируется нулевым QImage *, а loadPath () создает QImage в куче. Это заставляет меня везде проверять нулевой указатель. Я полагаю, что должен быть способ иметь экземпляр QImage, если файл может быть открыт, и конструкцию, которая просто не удастся, если файл не может.

Ответы [ 3 ]

2 голосов
/ 18 декабря 2009

Это зависит от MyImage Я думаю. Если в конструкторе MyImage есть исключение, оно должно завершиться ошибкой, прежде чем вы достигнете метода push_back. Это связано с тем, что конструктор будет запускаться до push_back (что логично, поскольку для передачи метода требуется значение). Таким образом, если этот шаг завершится неудачно и возникнет исключение, push_back никогда не будет достигнуто.

Вот несколько указателей:

1 голос
/ 18 декабря 2009

Как уже упоминали другие, если конструктор MyImage выдает, вы никогда не достигнете функции deque.push_back, так что это не будет проблемой. Кроме того, если он входит в функцию push_back и по какой-то причине выдает его, то объект deque останется неизменным. STL не позволяет методам изменять / повреждать контейнер в случае сбоя операции. Я не смог найти ничего о push_back добавлении в документации , так что вам, вероятно, не придется беспокоиться об этом, если у вас не хватает памяти или какого-то другого крайнего случая.

1 голос
/ 18 декабря 2009

Если MyImage(*dirIter) не удастся, вы не попадете в push_back, так что это не проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...