I have a virtual class, named Type, and to derived classes, Type1 and Type2.
class Type {
public:
virtual void print() = 0;
};
class Type1 : public Type {
public:
void print() { cout << "I am of type 1" << endl; }
};
class Type2 : public Type {
public:
void print() { cout << "I am of type 2" << endl; }
};
Depending on parameters the user will enter, I will instantiate one class or the other.
Then I want to have another class that will produce actions, depending on the type of the "Type" object given as parameter. For now, this class is :
class Action {
protected:
Type *t;
public:
Action(Type *t) : t(t) {} ;
void print() {
cout << "I am an action. My type says: ";
t->print();
}
};
How can I have Action::print produce different tasks depending on the type of the attribute "t"?
What I tried:
- Create two derived classes, namely Action1 and Action2, and instanciate Action1 if I instantiate Type1 (resp. Action2 and Type2). But this is exactly what I would like not to do: I would like Action to know "by itself" what to do.
- Define Action as a templated class (replacing Type by the template type). But in the same way, I have to instantiate an object of type Action< Type1> or Action< Type2>, what I would like not to do.
My wish is to have a main that looks like:
int main(int argc, const char * argv[]) {
Type *t = new Type1();
Action *act = new Action(t);
act->print();
delete act, t;
return 0;
}
But with a different print method called depending on the type of t. Is this possible (and how) or not?
Edit
After reading the comments, it turns that there are two main possible designs:
Create one class, Action, and call the specific method (print(Type1 *) or print(Type2 *)). I think this is the visitor pattern suggested in the comments.
Create two classes, Action1 and Action2 (possibly derived from Action, or not!), and instantiate the one that corresponds to t, Type1 or Type2.
Is one solution cleaner, easier to maintain, etc., than the other?
Edit 2
What about a Factory pattern, mentioned in some comments? Can anyone enlighten me about it solves or not my problem?