我如何向前声明一个内部类?(复制)

时间:2021-04-28 20:56:52

Possible Duplicate:
Forward declaration of nested types/classes in C++

可能的重复:c++中嵌套类型/类的前向声明

I have a class like so...

我有一门课……

class Container {
public:
    class Iterator {
        ...
    };

    ...
};

Elsewhere, I want to pass a Container::Iterator by reference, but I don't want to include the header file. If I try to forward declare the class, I get compile errors.

在其他地方,我希望通过引用传递一个容器::Iterator,但是我不想包含头文件。如果我尝试转发声明类,就会得到编译错误。

class Container::Iterator;

class Foo {
    void Read(Container::Iterator& it);
};

Compiling the above code gives...

编译上面的代码可以得到……

test.h:3: error: ‘Iterator’ in class ‘Container’ does not name a type
test.h:5: error: variable or field ‘Foo’ declared void
test.h:5: error: incomplete type ‘Container’ used in nested name specifier
test.h:5: error: ‘it’ was not declared in this scope

How can I forward declare this class so I don't have to include the header file that declares the Iterator class?

如何转发声明这个类,从而不必包含声明迭代器类的头文件?

3 个解决方案

#1


108  

This is simply not possible. You cannot forward declare a nested structure outside the container. You can only forward declare it within the container.

这根本不可能。不能在容器外转发声明嵌套结构。只能在容器中转发声明。

You'll need to do one of the following

您将需要执行以下操作之一

  • Make the class non-nested
  • 使类non-nested
  • Change your declaration order so that the nested class is fully defined first
  • 更改声明顺序,使嵌套类首先得到完整定义
  • Create a common base class that can be both used in the function and implemented by the nested class.
  • 创建一个通用基类,该基类可以在函数中使用,也可以由嵌套类实现。

#2


19  

I don't believe forward declaring inner class of on an incomplete class works (because without the class definition, there is no way of knowing if there actually is an inner class). So you'll have to include the definition of Container, with a forward declared inner class:

我不认为在不完整的类上声明内部类是可行的(因为没有类定义,就无法知道是否有内部类)。所以你必须包含容器的定义,包含一个前声明的内部类:

class Container {
public:
    class Iterator;
};

Then in a separate header, implement Container::Iterator:

然后在一个单独的header中,实现Container::Iterator:

class Container::Iterator {
};

Then #include only the container header (or not worry about forward declaring and just include both)

然后,#只包含容器的标题(或者不担心转发,只包含两个)

#3


1  

I know of no way to do exactly what you want, but here is a workaround, if you are willing to use templates:

我知道没有办法确切地做你想做的,但是如果你愿意使用模板,这里有一个解决方案:

// Foo.h  
struct Foo
{
   export template<class T> void Read(T it);
};

// Foo.cpp
#include "Foo.h"
#include "Container.h"
/*
struct Container
{
    struct Inner { };
};
*/
export template<> 
  void Foo::Read<Container::Inner>(Container::Inner& it)
{

}

#include "Foo.h"
int main()
{
  Foo f;
  Container::Inner i;
  f.Read(i);  // ok
  f.Read(3);  // error
}

Hopefully, this idiom might be of some use to you (and hopefully your compiler is EDG-based and implements export ;) ).

希望这个习惯用法对您有所帮助(希望您的编译器基于edg并实现export;)。

#1


108  

This is simply not possible. You cannot forward declare a nested structure outside the container. You can only forward declare it within the container.

这根本不可能。不能在容器外转发声明嵌套结构。只能在容器中转发声明。

You'll need to do one of the following

您将需要执行以下操作之一

  • Make the class non-nested
  • 使类non-nested
  • Change your declaration order so that the nested class is fully defined first
  • 更改声明顺序,使嵌套类首先得到完整定义
  • Create a common base class that can be both used in the function and implemented by the nested class.
  • 创建一个通用基类,该基类可以在函数中使用,也可以由嵌套类实现。

#2


19  

I don't believe forward declaring inner class of on an incomplete class works (because without the class definition, there is no way of knowing if there actually is an inner class). So you'll have to include the definition of Container, with a forward declared inner class:

我不认为在不完整的类上声明内部类是可行的(因为没有类定义,就无法知道是否有内部类)。所以你必须包含容器的定义,包含一个前声明的内部类:

class Container {
public:
    class Iterator;
};

Then in a separate header, implement Container::Iterator:

然后在一个单独的header中,实现Container::Iterator:

class Container::Iterator {
};

Then #include only the container header (or not worry about forward declaring and just include both)

然后,#只包含容器的标题(或者不担心转发,只包含两个)

#3


1  

I know of no way to do exactly what you want, but here is a workaround, if you are willing to use templates:

我知道没有办法确切地做你想做的,但是如果你愿意使用模板,这里有一个解决方案:

// Foo.h  
struct Foo
{
   export template<class T> void Read(T it);
};

// Foo.cpp
#include "Foo.h"
#include "Container.h"
/*
struct Container
{
    struct Inner { };
};
*/
export template<> 
  void Foo::Read<Container::Inner>(Container::Inner& it)
{

}

#include "Foo.h"
int main()
{
  Foo f;
  Container::Inner i;
  f.Read(i);  // ok
  f.Read(3);  // error
}

Hopefully, this idiom might be of some use to you (and hopefully your compiler is EDG-based and implements export ;) ).

希望这个习惯用法对您有所帮助(希望您的编译器基于edg并实现export;)。