Pergunta sobre c++, forward-declaration – Como faço para encaminhar declarar uma classe interna? [duplicado]

133

Duplicata Possível:
Encaminhar declaração de tipos / classes aninhados em C ++

Eu tenho uma aula assim ...

<code>class Container {
public:
    class Iterator {
        ...
    };

    ...
};
</code>

Em outro lugar, quero passar um Container :: Iterator por referência, mas não quero incluir o arquivo de cabeçalho. Se eu tentar encaminhar declarar a classe, recebo erros de compilação.

<code>class Container::Iterator;

class Foo {
    void Read(Container::Iterator& it);
};
</code>

Compilar o código acima dá ...

<code>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
</code>

Como posso encaminhar declarar essa classe para que eu não precise incluir o arquivo de cabeçalho que declara a classe Iterator?

Eu encontrei uma soluçãoligação bitlixi

Sua resposta

3   a resposta
1

mas aqui está uma solução alternativa, se você estiver disposto a usar modelos:

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

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

Espero que este idioma possa ser de alguma utilidade para você (e esperamos que seu compilador seja baseado em EDG e implemente exportação;)).

20

mpleta funciona (porque sem a definição de classe, não há como saber se há realmenteé uma classe interna). Então você terá que incluir a definição de Container, com uma classe interna declarada para frente:

<code>class Container {
public:
    class Iterator;
};
</code>

Então, em um cabeçalho separado, implemente o Container :: Iterator:

<code>class Container::Iterator {
};
</code>

Em seguida, #include apenas o cabeçalho do contêiner (ou não se preocupe com o forward declarando e apenas inclua ambos)

Boa resposta, exceto a parte do parêntese do primeiro parágrafo. O "não há como saber se existe realmente uma classe interna" não faz sentido neste contexto e é duvidoso que seja preciso. O ponto principal de uma declaração antecipada é que você está dizendo ao compilador que existe uma classe (ou, neste caso, uma classe interna). Essa declaração específica de vocês seria tão verdadeira quanto as classes normais e significaria que você não pode encaminhar declarar nada. Loduwijk
117

a estrutura aninhada fora do contêiner. Você só pode encaminhar declará-lo dentro do contêiner.

Você precisará fazer um dos seguintes

Torne a turma não aninhadaAltere sua ordem de declaração para que a classe aninhada seja totalmente definida primeiroCrie uma classe base comum que possa ser usada na função e implementada pela classe aninhada.
@ HelloGoodbye Eu tenho a sensação de que a incorporação de declarações em classes são superestimadas. Não é comparável a declarações e definições em namespaces, mesmo se o acesso via:: parece semelhante. Talvez os casos em que os programadores desejem ter permissão para encaminhar declarar uma classe dentro de uma classe apenas surjam de um projeto defeituoso. C ++ como uma linguagem já é muito abundante e sua combinatória parece ser demais para os designers também ... Eu não sei se seria uma boa idéia esperar que isso fosse estimado como um recurso a ser adicionado. Wolf
@ HelloGoodbye Eu acho que os modificadores de acessibilidade são a limitação: você não sabe onde colocá-los (e se você deve ser permitido). Wolf
@Wolf Você tem um ponto aí. Não seria possível especificar isso incluindo os modificadores na expressão de declaração avançada? Por exemplo.class Container::(public Iterator), ou algo assim? (Não estou falando sobre como a linguagem é projetada hoje, mas sobre como teoricamente ela poderia ser projetada.) HelloGoodbye
A classe base comum é a solução mais usada no meu final. Coyote

Perguntas relacionadas