Reputation: 10882
I have a small Factory class
implemented in Java
. Its minimized version looks like so:
interface MyClass{
public void doSomething();
}
class Concrete_1 implements MyClass{
private String field_1;
Concrete_1(String _field_1){
// ... initialization
}
public void doSomething(){
// ... not so important
}
}
class MyClassFactory{
public static MyClass init(int idx, String val){
Concrete_1 ex = null;
switch(idx){
case 1:
ex = new Concrete_1(val);
break;
default:
break;
}
return ex;
}
public static void main(String args[]){
MyClass ex = MyClassFactory.init(1, "value"); // <-- I like that
}
}
I like the way it works and especially the way, how I can instantiate particular objects, like:
MyClass ex = MyClassFactory.init(1, "value");
Now what I want is to implement the same thing in C++. I've seen some examples (including some threads at stackoverflow), but in all those examples they use an abstarct class (instead of an interface in my case of Java). And if memory servers me right, it is impossible to create instances of an abstract class. So, if we simply port the code above to C++ and use some abstract class instead of the interface, it will not work, because this is forbiden:
MyClass ex = MyClassFactory.init(1, "value"); // <-- MyClass now is abstract
// so this is illegal
My question is how can I do exactly the same thing in C++? Thanks!
Upvotes: 2
Views: 116
Reputation: 2365
You can use pointers or references for handling those. Eg.
std::shared_pointer<MyClass> ptrClass = MyClassFactory.init(1, "value");
As Factories in C++ usually returns pointers, then you will probably stick with the pointer option. And hint: Do not use raw pointers. use shared pointers or unique pointers instead and return shared pointers from Factories.
More complete solution will be:
class MyClassFactory{
public:
MyClass* init(int idx, std::string val){
switch(idx){
case 1:
return new Concrete_1;
default:
return nullptr;
}
}
};
ADDITION 1:
About returning type of factory please look at: What is the best smart pointer return type for a factory function?
people commented about it. I finally left it as non-smart pointer, and wheather it's a good idea or not please look at the link above. In my opinion smart_pointers should be used always, but as you wish.
Upvotes: 2
Reputation: 4319
In C++ it can be reached via pointers:
struct MyClass{
virtual void doSomething() = 0;
};
class Concrete_1 : public MyClass {
String field_1;
public:
Concrete_1(String _field_1){
// ... initialization
};
void doSomething(){
// ... not so important
}
};
class MyClassFactory{
public:
std::shared_ptr<MyClass> init(int idx, String val){
switch(idx){
case 1:
return std::shared_ptr<MyClass>(new Concrete_1(val));
}
return std::shared_ptr<MyClass>();
}
};
int main(...) {
std::shared_ptr<MyClass> ex = MyClassFactory::init(1, "value");
}
Upvotes: 3
Reputation: 409482
The difference between Java and C++ in this case is that in C++ you have to use pointers.
Create the concrete class using new
, and return it as a pointer to the base-class.
Upvotes: 1