Including multiple headers for achieving polymorphism

Viewed 139

I have an interface ver as

// ver.h
class ver
{
    public:
    virtual void func()=0;
};

Then ver1 and ver2 implement this interface. ver1 and ver2 differ in the sense they include header test\header.h and test2\header.h. Now test\header.h and test2\header.h are not under my control and are mostly similar except for a function pointer which is the reason for having ver1 and ver2

// test\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_a
);   
#endif

and

// test2\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
 struct_type_b
);   
#endif

Now the implementations

//ver1.h
#include "test\header.h"
class ver1:public ver
{
    public:
        FuncPoint f;
};

and

//ver2.h
#include "test2\header.h"
class ver2:public ver
{
    public:
        FuncPoint f;
};

and ver1.cpp and ver2.cpp will be using the respective f

Now the polymorphic behavior comes into play here

//something.cpp

#include "ver.h"
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
    if (some_condition)
        return new ver1();
    else
        return new ver2();
}

Since something.cpp includes both ver1.h and ver2.h, first test\header1.h gets included and because of the include guards, test\header2.h is not included and hence there is no FuncPoint defined for class ver2 and something.cpp fails to compile. On the other hand ver1.cpp and ver2.cpp gets compiled successfully since there is only one header.h included.

I could do a #undef header after including ver1.h in something.cpp but that would give redefinition error for other things which are same in test\header.h1 and tes\header2.h.

A simple fix would be to not have FuncPoint f as global variables instead of member variables, this way i won't have to include test\header.h in ver1.h but instead in ver1.cpp.

Is there some other better way to fix this?

EDIT: I could forward declare struct_type_a and struct_type_b in something.cpp and avoid including ver1.h and ver2.h in something.cpp. But class ver1 and ver2 use other things(to declare members) from test\header.h as well(which are same in both versions).

1 Answers

Don't include header.h in ver1.h or ver2.h but in the respective .cpp files: FuncPoint is a pointer so you can use forward declarations. Since ver1.h and ver2.h will both be included you will need to rename it however where exposed (in the .cpp files you will be able to use the original FuncPoint too, since you include only one definition of it there):

//ver1.h
#include "ver.h"
struct struct_type_a;
typedef void (*FuncPoint_a)(struct_type_a); 
class ver1 : public ver
{
    public:
        FuncPoint_a f;
        static ver1 *create();
};

Also the creation of the polymorphic objects must be demanded to methods implemented in the .cpp files, in the create() static method.

Following your code it would become:

//something.cpp
#include "ver.h"    
#include "ver1.h"
#include "ver2.h"
ver* somefunc()
{
    if (some_condition)
        return ver1::create();
    else
        return ver2::create();
}

In this way the two colliding headers will never be included in the same file.

I've added the inclusion of ver.h in ver1.h (and ver2.h) because this is the source using it. Including it in something.cpp only is not correct (ver1 and ver2 need it) - but not related to the current problem.

Related