为什么编译器不让我向前声明类型定义?

假设这是不可能的,那么保持我的包含树小的最佳实践是什么?


当前回答

要“fwd声明一个类型定义”,你需要fwd声明一个类或结构,然后你可以typedef声明类型。编译器可以接受多个相同的类型。

长形式:

class MyClass;
typedef MyClass myclass_t;

简式:

typedef class MyClass myclass_t;

其他回答

要“fwd声明一个类型定义”,你需要fwd声明一个类或结构,然后你可以typedef声明类型。编译器可以接受多个相同的类型。

长形式:

class MyClass;
typedef MyClass myclass_t;

简式:

typedef class MyClass myclass_t;

因为要声明一个类型,就需要知道它的大小。可以前向声明指向该类型的指针,也可以对指向该类型的指针进行类型定义。

如果您真的想这样做,您可以使用pimpl习语来减少包含。但是如果你想使用类型,而不是指针,编译器必须知道它的大小。

Edit: j_random_hacker为这个答案添加了一个重要的限定条件,基本上是需要知道该类型的大小才能使用该类型,但是如果我们只需要知道该类型的存在,就可以进行前向声明,以便创建指向该类型的指针或引用。由于OP没有显示代码,但抱怨它不会编译,我假设(可能是正确的)OP试图使用类型,而不仅仅是引用它。

我也有同样的问题,不想在不同的文件中混淆多个typedef,所以我用继承解决了它:

was:

class BurstBoss {

public:

    typedef std::pair<Ogre::ParticleSystem*, bool> ParticleSystem; // removed this with...

did:

class ParticleSystem : public std::pair<Ogre::ParticleSystem*, bool>
{

public:

    ParticleSystem(Ogre::ParticleSystem* system, bool enabled) : std::pair<Ogre::ParticleSystem*, bool>(system, enabled) {
    };
};

效果很好。当然,我必须改变所有的参考资料

BurstBoss::ParticleSystem

简单地

ParticleSystem

另一个解决方案是将forward声明和typedefs放在一个单独的头文件中,并包括:

// ForwardDeclarations.h
#pragma once
namespace Foo
{
    struct Bar;
    typedef Bar Baz;
}

// SomeFile.h
#include "ForwardDeclarations.h"
Foo::Baz baz;

当然,这实际上并没有减少要包含的文件数量,编译器仍然必须从磁盘读取这个文件,但至少内容比完整的定义更简单。您可以在同一个文件中添加更多的前向声明,并将其包含在相关位置。

对于那些像我一样,希望在一些c++代码中前向声明使用typedef定义的c风格结构体的人,我已经找到了一个解决方案,如下所示…

// a.h
 typedef struct _bah {
    int a;
    int b;
 } bah;

// b.h
 struct _bah;
 typedef _bah bah;

 class foo {
   foo(bah * b);
   foo(bah b);
   bah * mBah;
 };

// b.cpp
 #include "b.h"
 #include "a.h"

 foo::foo(bah * b) {
   mBah = b;
 }

 foo::foo(bah b) {
   mBah = &b;
 }