Recentemente, fiquei preso em uma situação como esta:
class A
{
public:
typedef struct/class {...} B;
...
C::D *someField;
}
class C
{
public:
typedef struct/class {...} D;
...
A::B *someField;
}
Geralmente você pode declarar um nome de classe:
class A;
Mas você não pode encaminhar declarar um tipo aninhado, o seguinte causa erro de compilação.
class C::D;
Alguma ideia?
c++
class
nested
forward-declaration
Calmarius
fonte
fonte
Respostas:
Você não pode fazer isso, é um buraco na linguagem C ++. Você precisará cancelar o aninhamento de pelo menos uma das classes aninhadas.
fonte
Eu precisava de uma referência direta como:
Minha solução alternativa foi:
Mais tarde, quando eu poderia usar a definição completa:
Essa técnica provavelmente seria mais problemática do que vale a pena se houvesse construtores complicados ou outras funções especiais de membros que não fossem herdadas sem problemas. Eu poderia imaginar certas mágicas reagindo mal.
Mas, no meu caso muito simples, parece funcionar.
fonte
using basename::basename;
na classe derivada, portanto, não há problema com ctors complicados.typedef
dentro da classeSe você realmente deseja evitar # incluir o arquivo de cabeçalho desagradável no seu arquivo de cabeçalho, faça o seguinte:
arquivo hpp:
arquivo cpp
Mas então:
Então, sim, trocas ...
fonte
hpp
arquivo?Isso pode ser feito declarando a classe externa como um espaço para nome .
Exemplo: Temos que usar uma classe aninhada others :: A :: Nested in others_a.h, que está fora de nosso controle.
others_a.h
my_class.h
my_class.cpp
fonte
a::b
é confundido da mesma maneira, não importa sea
é classe ou espaço para nome.Eu não chamaria isso de resposta, mas, mesmo assim, uma descoberta interessante: se você repetir a declaração de sua estrutura em um espaço para nome chamado C, está tudo bem (pelo menos no gcc). Quando a definição de classe de C é encontrada, ela substitui silenciosamente o espaço de nome C.
fonte
Isso seria uma solução alternativa (pelo menos para o problema descrito na pergunta - não para o problema real, ou seja, quando não houver controle sobre a definição de
C
):fonte
Se você tiver acesso para alterar o código fonte das classes C e D, poderá retirar a classe D separadamente e inserir um sinônimo para ela na classe C:
fonte