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

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


当前回答

我也有同样的问题,不想在不同的文件中混淆多个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

其他回答

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

长形式:

class MyClass;
typedef MyClass myclass_t;

简式:

typedef class MyClass myclass_t;

正如Bill Kotsias所指出的,保持点的typedef细节为私有并向前声明的唯一合理方法是继承。不过,使用c++ 11可以做得更好一些。考虑一下:

// LibraryPublicHeader.h

class Implementation;

class Library
{
...
private:
    Implementation* impl;
};
// LibraryPrivateImplementation.cpp

// This annoyingly does not work:
//
//     typedef std::shared_ptr<Foo> Implementation;

// However this does, and is almost as good.
class Implementation : public std::shared_ptr<Foo>
{
public:
    // C++11 allows us to easily copy all the constructors.
    using shared_ptr::shared_ptr;
};

我也有同样的问题,不想在不同的文件中混淆多个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++(而不是普通C)中,对一个类型定义两次是完全合法的,只要两个定义完全相同:

// foo.h
struct A{};
typedef A *PA;

// bar.h
struct A;  // forward declare A
typedef A *PA;
void func(PA x);

// baz.cc
#include "bar.h"
#include "foo.h"
// We've now included the definition for PA twice, but it's ok since they're the same
...
A x;
func(&x);