2009-12-18 2 views
2

다음과 같은 것이 있습니다 :MyClass 생성자가 던져 넣을 수있는 MyClass의 컨테이너를 생성하는 방법?

#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는 null QImage *로 초기화되고 loadPath()는 QImage 힙에. 이로 인해 모든 곳에서 널 포인터 검사가 발생합니다. 나는 파일을 열 수 있다면 QImage의 인스턴스를 가질 수있는 방법이 있어야하고, 파일을 열 수 없다면 생성이 실패 할 것이라고 생각한다.

+1

값이 아닌 const 참조를 사용하여 캐치합니다. –

+0

QDir과 친구들이 바로 거기에있을 때 Boost를 사용하여 경로를 관리하는 이유는 무엇입니까? 또한 deque는 쓸모가 없습니다. QList는 많은 경우에 매우 훌륭하게 수행되며 더 깨끗하고 사용하기 쉬운 API를 제공합니다. – CMircea

+1

QList 인터페이스는 어떻게 더 좋습니까? 그것은 나에게 똑같이 보입니다. – Skurmedel

답변

2

에 따라 달라집니다. MyImage에 따라 다릅니다. MyImage의 생성자에 예외가있는 경우 push_back 메서드에 도달하기 전에 오류가 발생합니다. 이것은 생성자가 push_back (논리적인데, 메서드를 전달하는 값이 필요하기 때문에) 전에 실행되기 때문입니다. 따라서 해당 단계가 실패하고 예외가 발생하면 push_back에 도달하지 않습니다.

는 여기에 몇 가지 포인터 :

1

MyImage(*dirIter) 당신이 push_back로받지 않습니다 실패하면 그래서 그 문제가되지 않습니다.

1

다른 사람들이 이미 언급했듯이 MyImage 생성자가 throw하는 경우 함수에 도달하지 않으므로 문제가되지 않습니다. 또한 push_back 함수로 만들면 어떤 이유로 던져지면 deque 객체는 변경되지 않습니다. STL은 조작이 실패 할 경우 메소드가 컨테이너를 수정/손상시킬 수 없도록합니다. 내가 documentation에 던지고 push_back에 대해 아무것도 찾을 수 없었습니다, 그래서 당신은 아마도 메모리 또는 다른 극단적 인 경우를 다 떨어지지 않는 한 그것에 대해 걱정할 필요가 없습니다.

관련 문제