Reputation: 803
I have "like factory" class:
class SpecialReader {
private:
HANDLE specialFile;
SpecialReader(HANDLE specialFile);
public:
static SpecialReader Create(TCHAR* fileName);
~SpecialReader();
}
//where
SpecialReader::Create(TCHAR* fileName) {
// ...
// ...
return SpecialReader(inputFile);
}
I want to define object in program body like this:
SpecialReader myReader;
But not:
SpecialReader myReader = SpecialReader::Create(anyFile);
If I try to define object like in the first case I've got a compiler error:
error C2512: 'SpecialReader' : no appropriate default constructor available.
How to define this class right?
Upvotes: 2
Views: 169
Reputation: 1
You can use a smart pointer to do so, the simplest choice is using a std::unique_ptr<SpecialReader>
and transfer ownership of the instance to the caller:
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));
}
To get delayed creation you can write as follows. The syntax is slightly different from your OP, but effectively achieves the same:
std::unique_ptr<SpecialReader> myReader;
// ....
myReader = SpecialReader::Create(filename);
As for your comments, that you want to handle failure within the Create()
factory function, you can return an empty std::unique_ptr<SpecialReader>
, and let the client check about it:
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
}
Upvotes: 2
Reputation: 45
Why not have a do-nothing default constructor?
public:
SpecialReader(){};
Upvotes: 1