C++ 在头文件中正向声明另一命名空间的自定义类型

C++ 在头文件中正向声明另一命名空间的自定义类型,c++,C++,我正在使用一个名为custom(不是实际名称)的外部库,它在自己的名称空间中定义了许多数据类型。让我们假设名称空间也命名为custom 我正在尝试使用名为datatype的数据类型DataType是使用typedef定义的自定义类型,我们假设它可以通过包含“custom/DataType.h” 我的代码具有以下设置 行动.h: class Action { Action() {} virtual ~Action() {} virtual void foo(custom:

我正在使用一个名为custom(不是实际名称)的外部库,它在自己的名称空间中定义了许多数据类型。让我们假设名称空间也命名为
custom

我正在尝试使用名为
datatype
的数据类型
DataType
是使用typedef定义的自定义类型,我们假设它可以通过包含
“custom/DataType.h”

我的代码具有以下设置

行动.h:

class Action
{
    Action() {}
    virtual ~Action() {}

    virtual void foo(custom::DataType*) const = 0;
    ...
}
一些行动。h:

#include "action.h"

class SomeAction : public Action
{
    SomeAction() {}

    virtual void foo(custom::DataType*) const override;
    ...
}
一些_action.cpp:

#include "some_action.h"
#include "custom/datatype.h"
...
void SomeAction::foo(custom::DataType*) const
{
    ...
}

除了在
action.h
中包含
“custom/DataType.h”
之外,是否有合适的方法在
action.h
中转发声明
数据类型
某些操作.h
,然后您可以在
action.h
中转发声明:

namespace custom {
  class DataType1;

  enum DataType2 : int; 
}
缺点是,当您更新库时,它可能会中断。编写良好的库可能会有一个头,头中除了转发声明之外什么都没有,您可以使用它,因此可以查找这些声明(例如:
iosfwd


否则,没有办法包含库编写器提供的标题。

如果
数据类型是类类型或具有基础整数类型的枚举,则可以在
操作.h
中向前声明它:

namespace custom {
  class DataType1;

  enum DataType2 : int; 
}
缺点是,当您更新库时,它可能会中断。编写良好的库可能会有一个头,头中除了转发声明之外什么都没有,您可以使用它,因此可以查找这些声明(例如:
iosfwd

否则,将无法包含库编写器提供的标题

除了在
action.h
中包含
“custom/DataType.h”
之外,是否有合适的方法来定义
action.h
中的
数据类型
一些动作.h

您可能不想“定义”
数据类型,而是想定义它。这允许您让编译器知道稍后将定义的
custom::DataType

您可以通过以下方式实现这一点。在
action.h
some_action.h
中添加以下正向声明:

在需要定义
数据类型的
.cpp
文件中,包括
“custom/DataType.h”


如果
custom::DataType
是类型别名(即
typedef
),则需要包含标题。没有向前声明类型别名的方法:请参阅以获取相关信息

除了在
action.h
中包含
“custom/DataType.h”
之外,是否有合适的方法来定义
action.h
中的
数据类型
一些动作.h

您可能不想“定义”
数据类型,而是想定义它。这允许您让编译器知道稍后将定义的
custom::DataType

您可以通过以下方式实现这一点。在
action.h
some_action.h
中添加以下正向声明:

在需要定义
数据类型的
.cpp
文件中,包括
“custom/DataType.h”



如果
custom::DataType
是类型别名(即
typedef
),则需要包含标题。没有向前声明类型别名的方法:请参阅以获取相关信息。

您的代码是否编译?在action.h中,您至少需要一个
数据类型的转发声明
@tobi303我的代码确实没有编译。这就是为什么我问如何处理这个问题。如果按照当前的方式编译代码,编译器会认为头文件中的
自定义
数据类型
未定义。如果我按照维托里奥·罗密欧的回复中的建议转发声明,我会得到另一个错误。(关于实际错误,请参阅我对他的回答的评论)在这种情况下,您应该在问题“您的代码是否编译?”?在action.h中,您至少需要一个
数据类型的转发声明
@tobi303我的代码确实没有编译。这就是为什么我问如何处理这个问题。如果按照当前的方式编译代码,编译器会认为头文件中的
自定义
数据类型
未定义。如果我按照维托里奥·罗密欧的回复中的建议转发声明,我会得到另一个错误。(请参阅我对他回答中实际错误的评论)在这种情况下,您应该在问题中包含错误消息。我最初也这么认为,但不幸的是,正如我在问题中指出的,它是由typedef定义的。它的定义基于custom(即library)中使用的一些其他内部数据类型,这些数据类型也位于命名空间
custum
@ilim中-那么我的答案中的最后一句恐怕适用。我最初也这么认为,但不幸的是,正如我在问题中指出的,它是由typedef定义的。它的定义基于custom(即library)中使用的一些其他内部数据类型,这些数据类型也位于命名空间
custum
@ilim中-那么我的答案中的最后一句恐怕适用。正如我在问题中提到的,它是由typedef定义的。它的定义实际上是基于custom(即library)中使用的某些其他内部数据类型,该数据类型也位于命名空间
custum
中。因此,当我按照您建议的方式转发声明时,在编译时会出现以下错误:“错误C2371:‘自定义::数据类型’:重新定义;不同的基本类型”@ilim:我错过了道歉-编辑了我的答案。您不能真正向前声明
typedef
。正如我在问题中提到的,它是由typedef定义的。它的定义实际上是基于custom(即library)中使用的某些其他内部数据类型,该数据类型也位于命名空间
custum
中。所以当我支持战争的时候