2015-04-29 2 views
2

Я "как завод" класса:Определить класс фабрики в C++

class SpecialReader { 
private: 
    HANDLE specialFile; 
    SpecialReader(HANDLE specialFile); 
public: 
    static SpecialReader Create(TCHAR* fileName); 
    ~SpecialReader(); 
} 

//where 

SpecialReader::Create(TCHAR* fileName) { 
// ... 
// ... 

return SpecialReader(inputFile); 
} 

Я хочу, чтобы определить объект в теле программы, как это:

SpecialReader myReader; 

Но нет:

SpecialReader myReader = SpecialReader::Create(anyFile); 

Если я попытаюсь определить объект, как в первом случае, у меня возникла ошибка компилятора:

error C2512: 'SpecialReader' : no appropriate default constructor available. 

Как определить этот класс правильно?

+0

Вы пытались дать ему соответствующий конструктор по умолчанию? Хотя, возможно, лучше не делать этого; сложнее использовать класс неправильно, если не разрешить построение по умолчанию. –

+0

Я хочу отключить возможность создания объекта без метода Create. –

+6

Вы уже это сделали. Но в вашем вопросе говорится иначе: в нем говорится, что вы хотите иметь возможность создавать по умолчанию. Вы не можете позволить и запретить это. –

ответ

2

Вы можете использовать smart pointer сделать это, самый простой выбор с помощью std::unique_ptr<SpecialReader> и передачи права собственности экземпляра к абоненту:

class SpecialReader { 
private: 
    HANDLE specialFile; 
    SpecialReader(HANDLE specialFile);   
public: 
    static std::unique_ptr<SpecialReader> Create(TCHAR* fileName); 
     // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
    ~SpecialReader(); 
} 

std::unique_ptr<SpecialReader> SpecialReader::Create(TCHAR* fileName) { 
    // ... 
    return std::unique_ptr<SpecialReader>(new SpecialReader(inputFile)); 
} 

Чтобы получить замедленное создание вы можете написать следующим образом. Синтаксис немного отличается от вашего ОП, но эффективно достигается тот же:

std::unique_ptr<SpecialReader> myReader; 

// .... 

myReader = SpecialReader::Create(filename); 

Что касается ваших комментариев, что вы хотите, чтобы справляться с неудачами в функции Create() фабрики, вы можете вернуть пустой std::unique_ptr<SpecialReader>, и пусть чек клиента об этом:

std::unique_ptr<SpecialReader> SpecialReader::Create(TCHAR* fileName) { 
    try { 
     // ... 
     return std::unique_ptr<SpecialReader>(new SpecialReader(inputFile)); 
    } 
    catch(...) { 
     // ignore any exceptions 
    } 
    return std::unique_ptr<SpecialReader>(); 
} 

std::unique_ptr<SpecialReader> myReader; 
myReader = SpecialReader::Create(filename); 
if(!myReader.get()) { 
    // Error handling, Create() couldn't create an instance of SpecialReader 
} 
+0

Друг std :: make_unique (TCHAR * fileName); ошибка C2063: 'std :: make_unique' не является функцией –

+0

Вы включили заголовок 'memory' и ваш компилятор способен к стандартным функциям C++ 14? Вместо использования 'std :: make_unique()' вы также можете использовать 'return std :: unique_ptr (новый SpecialReader (inputFile));'. –

+0

Да, я включаю заголовок памяти. Второй вариант работает отлично (return std :: unique_ptr ...). Но как удалить созданный объект? –

1

Почему бы не делать-н othing default constructor?

public: 
    SpecialReader(){}; 
+0

Если вы прочитаете вопрос, вы поймете, что OP не хочет этого (по тем или иным причинам). Только фабричная функция должна иметь возможность создавать новые экземпляры 'SpecialReader'. –

Смежные вопросы