我的接口ver
为
// ver.h
class ver
{
public:
virtual void func()=0;
};
然后ver1
和ver2
实现此接口。 ver1
和ver2
在包括标头test\header.h
和test2\header.h
的意义上有所不同。现在test\header.h
和test2\header.h
不在我的控制之下,并且除了函数指针(它们是拥有ver1
和ver2
// 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.cpp
和ver2.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.h
和ver2.h
,因此首先包含了test\header1.h
,并且由于包含保护,因此不包含test\header2.h
,因此存在没有为FuncPoint
和class ver2
定义的something.cpp
编译失败。
另一方面,ver1.cpp
和ver2.cpp
成功编译,因为其中仅包含一个header.h
。
在#undef header
中包含ver1.h
之后,我可以做一个something.cpp
,但是对于在test\header.h1
和tes\header2.h
中相同的其他事情,这会带来重新定义错误。
一个简单的解决方法是不将FuncPoint f
作为全局变量而不是成员变量,这样我就不必在test\header.h
中包括ver1.h
而是在{{1 }}。
还有其他更好的方法来解决此问题吗?
编辑:
我可以在ver1.cpp
中声明struct_type_a
和struct_type_b
,并避免在something.cpp
中包含ver1.h
和ver2.h
。但是类something.cpp
和ver1
也使用ver2
中的其他东西(声明成员)(两个版本中都相同)。
答案 0 :(得分:2)
不要在header.h
或ver1.h
中包含ver2.h
,而是在各自的.cpp文件中:FuncPoint
是一个指针,因此您可以使用前向声明。由于ver1.h
和ver2.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需要它),但与当前问题无关。