包含多个标头以实现多态性

use*_*404 5 c++

我有一个界面ver作为

// ver.h
class ver
{
    public:
    virtual void func()=0;
};
Run Code Online (Sandbox Code Playgroud)

然后ver1ver2实现此接口.ver1并且ver2它们包括标题test\header.htest2\header.h.现在test\header.h并且test2\header.h不在我的控制之下,并且除了函数指针之外大部分都是相似的,这是使用ver1和的原因ver2

// test\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
struct_type_a
);   
#endif
Run Code Online (Sandbox Code Playgroud)

// test2\header.h
#ifndef header
#define header
typedef void
(*FuncPoint)(
 struct_type_b
);   
#endif
Run Code Online (Sandbox Code Playgroud)

现在实现

//ver1.h
#include "test\header.h"
class ver1:public ver
{
    public:
        FuncPoint f;
};
Run Code Online (Sandbox Code Playgroud)

//ver2.h
#include "test2\header.h"
class ver2:public ver
{
    public:
        FuncPoint f;
};
Run Code Online (Sandbox Code Playgroud)

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();
}
Run Code Online (Sandbox Code Playgroud)

由于something.cpp包括both ver1.hver2.h,首先test\header1.h包含并且由于包含保护,test\header2.h因此不包括在内,因此没有FuncPoint定义class ver2something.cpp编译失败.另一方面ver1.cpp,ver2.cpp由于只header.h包含一个,因此可以成功编译.

我可以做一个#undef header包括之后ver1.hsomething.cpp,但将给予重新定义错误其他东西是一样中 test\header.h1tes\header2.h.

一个简单的解决将是没有FuncPoint f为全局变量,而不是成员变量,这样我就不必包括test\header.hver1.h而是在ver1.cpp.

还有其他更好的解决方法吗?

编辑:我可以转发声明struct_type_astruct_type_b进入something.cpp并避免包含ver1.hver2.h进入something.cpp.但是ver1同时ver2使用其他东西(以声明成员)test\header.h(在两个版本中都是相同的).

Sig*_*ndo 2

不要在各自的 .cpp 文件中包含header.hinver1.h或but :是一个指针,以便您可以使用前向声明。由于和都将被包含在内,因此您需要在暴露的位置重命名它(在 .cpp 文件中,您也可以使用原始文件,因为您只包含它的一个定义):ver2.hFuncPointver1.hver2.hFuncPoint

//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();
};
Run Code Online (Sandbox Code Playgroud)

此外,多态对象的创建必须要求在 .cpp 文件中的create()静态方法中实现。

按照你的代码,它将变成:

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

这样,两个冲突的标头将永远不会包含在同一个文件中。

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