C++ 转发未命名结构的声明
赏金问题:那么,这两个C++ 转发未命名结构的声明,c++,c,struct,typedef,forward-declaration,C++,C,Struct,Typedef,Forward Declaration,赏金问题:那么,这两个Foo不是一回事。好的第二种形式在图书馆中给出。如果我不能更改它,我如何转发声明它 我一直认为C和C++允许重复声明,只要没有重复的定义。当我试图编写C++代码时,遇到了这个问题,扩展了C库。 struct Foo; typedef struct {} Foo; 这会产生以下错误: “struct Foo”以前的声明为“struct Foo” 我要转发声明,该死!这里怎么了?您正在用相同的名称声明两个不同的实体。第一个名为struct Foo,是一个名为Foo的结构。第
Foo
不是一回事。好的第二种形式在图书馆中给出。如果我不能更改它,我如何转发声明它
<>我一直认为C和C++允许重复声明,只要没有重复的定义。当我试图编写C++代码时,遇到了这个问题,扩展了C库。
struct Foo;
typedef struct {} Foo;
这会产生以下错误:
“struct Foo”以前的声明为“struct Foo”
我要转发声明,该死!这里怎么了?您正在用相同的名称声明两个不同的实体。第一个名为
struct Foo
,是一个名为Foo
的结构。第二个是匿名结构的别名
如果您这样做:
struct Foo;
struct Foo {};
它是有效的,因为在这两种情况下都声明了名为Foo
的结构
不能转发声明匿名结构。剩下两个选择:包括整个定义,或者更改标题和结构名称。转发声明声明将有一个名为
Foo
的struct
您的第二个声明是名为
Foo
的typedef
。这些不是同一件事。您不需要在C++中键入def结构:
struct Foo; // Forward declaration
struct Foo
{
}; // Definition
如果您想在C中仅调用它Foo
,而不是struct Foo
,您确实需要typedef,这也可以通过不同的方式实现:
struct Foo; /* Forward declaration */
struct Foo /* The name is needed here */
{
}; /* Definition */
typedef struct Foo Foo; /* typedef */
或
当然可以在C和C++中使用表单<代码> StuttFoo< /Cuth.< /P> < P>对于TyPulf的前向声明,您需要引用正在被Type填充的东西,如:
struct foo;
typedef foo bar;
class foo{};
因为您想要正向声明匿名结构,所以您既不能在原始实体的正向声明中为它命名,也不能在类型定义时引用它。“逻辑”语法为:
struct ;
typedef bar;
class {};
但由于这显然是不可能的,所以不能向前声明匿名结构
要使用standardese,请看9.1-2:
仅由类密钥标识符组成的声明;要么是一个
在当前作用域或转发中重新声明名称
将标识符声明为类名。它介绍了这门课
将名称添加到当前范围中
没有标识符,没有转发声明
一句话:避免匿名结构,除非它们给了你真正需要的优势。IMHO,只需将你的
typedef
更改为
typedef struct Foo {} Foo;
^^^^^
不存在危害,在C+C++中仍适用。现在你可以向前申报了
[注意:如果您仍然坚持根本不触摸typedef
,那么下面是一个肮脏的把戏
只有当
Foo.h
只包含1个struct
声明时,这才有效。我不推荐它。]键入匿名结构是一种早于C++03的做法,主要是为了保持与C99之前编译器的兼容性
假定这是2011,C++和C都改变了,我想知道为什么没有这样一个库的最新版本! 如果它不再处于开发阶段,你就不能“离开”,而只是“生存”和改变,这是实现这一目标的方法。 如果仍在部署中,请将问题提交给开发团队
如果您需要一个解决方案,请考虑该结构可以继承。 所以,写一个向前的声明,比如
struct MyFoo;
并将其定义为
#include "old_library.h"
struct MyFoo: public Foo {};
在所有代码中,忘记
Foo
,始终使用MyFoo
您的特定编译器可能会产生不同
使用MinGW GCC 3.4.5,两个声明编译时都没有错误或警告(使用-Wall
)
及
库中是否可能已经存在转发声明?例如,要允许使用循环指针,请执行以下操作:
struct Foo;
typedef struct Foo {
struct Foo *fooPtr;
} Foo;
如果库标题中已经存在此错误,则会导致您描述的错误。为什么不直接避免转发decl呢
如果第二个定义在头文件中,可以在C++头文件中首先包含头文件。将C++看作是C标头,包含了包含“代码”>“外部”“C”{<代码> >代码> }/C>在大多数情况下都是足够的。
< p>因为它的未命名,所以不能向前声明它。它是一个未命名的结构,Foo是一个typedef。您正在尝试键入以前使用过的名称。该语句完全有效,只需使用其他名称即可struct Foo; // Forward declaration of struct Foo
typedef struct {} anotherFoo; // Another structure typedefed
struct Foo {
// Variables
}; // Definition of the forward declared Foo.
请注意,typedef不能用在同一个名称中。在类似的情况下,我有一个带有类似
== old_library.h ==
typedef struct { int data; } Foo;
== /old_library.h ==
我在自己的C++类中使用它,作为私有方法的参数:
class C {
void run(Foo *ds);
...
}
为了避免从C.hpp中包含“old#u library.h”,我使用以下转发声明:
class C {
struct Foo;
void run(Foo *ds);
...
}
在C.cpp中,我有以下陈述:
extern "C" {
#include "old_library.h"
}
struct C::Foo : public ::Foo {};
这样,我透明地使用C::Foo而不是Foo,并且不需要MyFoo 我想我最近遇到了与原始海报相同的问题,并已解决如下问题: 我正在围绕第三方提供的API编写一个包装器,定义如下: Foo.h:
typedef struct _foo
{
int i;
} Foo;
Foo* MakeFoo();
int UseFoo(Foo* foo);
我的包装器需要有Foo作为成员,但我不想向我的包装器的所有使用者公开Foo
UberFoo.h:
#pragma once
struct _foo; // forward declare the actual type _foo, not the typedef Foo
class UberFoo
{
public:
UberFoo();
int GetAnswer();
private:
_foo* f;
};
UberFoo.cpp:
#include "UberFoo.h"
#include "Foo.h"
UberFoo::UberFoo()
{
this->f = MakeFoo();
}
int UberFoo::GetAnswer()
{
return UseFoo(f);
}
现在,我的类的使用者可以实例化它,而无需访问_foo/foo的实际定义。如果我需要将指针作为参数传递给\u foo,或者从函数返回它们,并且需要有一个成员_foo,那么这也会起作用
main.cpp:
#include <cstdio>
#include "UberFoo.h"
int main(int argc, char* argv[])
{
UberFoo u;
printf( "The Answer = %d\n", u.GetAnswer());
return 0;
}
希望这有帮助 编译器是什么?另外,可能是空声明让它感到困扰?没有所谓的“C/C++”语言,特别是在结构上下文中。有太多的C++作者把代码“乱扔”在代码上,就像它是1989。@ Kerrek,在C++代码中没有什么错误。<代码>结构代码>代码,我用它来指示我写的是一个未封装的POD类型。@ SpAFF:我想Kerrek是指C“ID”。
typedef struct _foo
{
int i;
} Foo;
Foo* MakeFoo();
int UseFoo(Foo* foo);
#pragma once
struct _foo; // forward declare the actual type _foo, not the typedef Foo
class UberFoo
{
public:
UberFoo();
int GetAnswer();
private:
_foo* f;
};
#include "UberFoo.h"
#include "Foo.h"
UberFoo::UberFoo()
{
this->f = MakeFoo();
}
int UberFoo::GetAnswer()
{
return UseFoo(f);
}
#include <cstdio>
#include "UberFoo.h"
int main(int argc, char* argv[])
{
UberFoo u;
printf( "The Answer = %d\n", u.GetAnswer());
return 0;
}
typedef struct // the actual struct type underlying the typedef is anonymous here
{
int i;
} ThisWontWork;