views:

105

answers:

4

Edit: Thanks folks, now I see my mistake.

If I'm not wrong, because of its nature in factory method there is cyclic dependency:

Base class needs to know subclasses because it creates them, and subclasses need to know base class. Having cyclic dependency is bad programming practice, is not it?

Practically I implemented a factory, I have problem above, even I added

#ifndef MYCLASS_H
#define MYCLASS_H
#endif

I'm still getting

Compiler Error C2504 'class' : base class undefined

And this error disappers when I remove subclass include from base class header.

+3  A: 

Solution 1: don't #include the derived class headers in the base class header, only in the base class cpp. The declaration of the factory method should not use the type of concrete classes returned, only the base type.

Solution 2: use a separate factory class (or a factory method within a separate class) to create your objects. Then the cyclic dependency is totally eliminated. This is the preferred way.

Péter Török
Considering the best-practices, I guess second method is better, isn't it?
metdos
@metdos, it is - in the latest version of my answer I added a sentence to make this clear.
Péter Török
+4  A: 

The factory shouldn't be a base class of the products.

Andreas Brinck
Wow, good point!
metdos
A: 
struct Base {
    Base * Create(int param);
};

struct Derived0 : public Base {
};

struct Derived1 : public Base {
};

Base * Base::Create(int param) {
    switch (param) {
    case 0: return new Derived0();
    case 1: return new Derived1();
}

You should not try to implement the factory function within the Base class definition. Simply declare it there, and define it after the derived classes definitions.

Didier Trosset
His problem is related to having each subclass in a separate cpp/h file.
Salgar
@Salgar. Yes they are, and should I keep them that way?
metdos
You have Derived0 and Derived1 known within Base::Create(), so Base would need to be changed if you ever derive any more classes from it. That function needs to be moved out of Base.
jwismar
+1  A: 

Base classes never need to know about derived classes.

You need to revisit your pattern description, because I think you might be mixing a couple of different patterns together: if you're using it to create derived classes, then the factory shouldn't be part of the base class. If you're just using it to create various instances of a single class, then it could be a static member of that class.

In the error message you're getting above, the derived classes always need to know the full implementation of the base class. As a design matter, base classes should never know anything about derived classes.

jwismar