包括用于实现多态性的多个标头

时间:2019-01-17 09:05:41

标签: c++

我的接口ver

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

然后ver1ver2实现此接口。 ver1ver2在包括标头test\header.htest2\header.h的意义上有所不同。现在test\header.htest2\header.h不在我的控制之下,并且除了函数指针(它们是拥有ver1ver2

的原因之外,它们几乎相似)
// test\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_a
);   
#endif

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

现在实现

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

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

以及ver1.cppver2.cpp将使用各自的f

现在,多态行为在这里发挥作用

//something.cpp

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

由于something.cpp同时包含ver1.hver2.h,因此首先包含了test\header1.h,并且由于包含保护,因此不包含test\header2.h,因此存在没有为FuncPointclass ver2定义的something.cpp编译失败。 另一方面,ver1.cppver2.cpp成功编译,因为其中仅包含一个header.h

#undef header中包含ver1.h之后,我可以做一个something.cpp,但是对于在test\header.h1tes\header2.h中相同的其他事情,这会带来重新定义错误。

一个简单的解决方法是不将FuncPoint f作为全局变量而不是成员变量,这样我就不必在test\header.h中包括ver1.h而是在{{1 }}。

还有其他更好的方法来解决此问题吗?

编辑: 我可以在ver1.cpp中声明struct_type_astruct_type_b,并避免在something.cpp中包含ver1.hver2.h。但是类something.cppver1也使用ver2中的其他东西(声明成员)(两个版本中都相同)。

1 个答案:

答案 0 :(得分:2)

不要在header.hver1.h中包含ver2.h,而是在各自的.cpp文件中:FuncPoint是一个指针,因此您可以使用前向声明。由于ver1.hver2.h都将包含在内,因此您需要重命名它,但是在暴露的地方(在.cpp文件中,您也将能够使用原始的FuncPoint,因为您仅包含了//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(); }; 一种定义):

create()

此外,必须要求{.1pp}静态方法中.cpp文件中实现的方法都需要创建多态对象。

遵循您的代码,它将变成:

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

通过这种方式,两个冲突的标题将永远不会包含在同一文件中。

我在ver.h(和ver1.h)中添加了ver2.h,因为这是使用它的来源。仅将其包括在something.cpp中是不正确的(ver1和ver2需要它),但与当前问题无关。