Pergunta

Eu estou usando uma biblioteca parte 3 que tem uma declaração como esta:

typedef struct {} __INTERNAL_DATA, *HandleType;

E eu gostaria de criar uma classe que leva um HandleType no construtor:

class Foo
{
    Foo(HandleType h);
}

sem incluindo o cabeçalho que define HandleType . Normalmente, eu apenas voltada para o declarar tal tipo, mas eu não consigo descobrir a sintaxe para isso. Eu realmente quero dizer algo como:

struct *HandleType;

Mas que diz "identificador esperado antes *" no GCC. A única solução que vejo é para escrever a minha classe como este:

struct __INTERNAL_DATA;
class Foo
{
    Foo(__INTERNAL_DATA *h);
}

Mas isso depende de detalhes internos da biblioteca. Ou seja, ele usa o __INTERNAL_DATA nome, que é um detalhe de implementação.

Parece que ele deveria ser possível encaminhar-declare HandleType (parte da API pública) sem usar __INTERNAL_DATA (parte da implementação da biblioteca.) Alguém sabe como?

EDIT:. Adicionado mais detalhes sobre o que eu estou procurando

Foi útil?

Solução

Update:

Eu estou usando-o no CPP implementação de Foo, mas eu quero evitar incluí-lo na minha .h cabeçalho para Foo. Talvez eu esteja apenas sendo muito pedante? :)

Sim, você está :) Vá em frente com a declaração para a frente.

Se HandleType é parte da interface deve haver um cabeçalho declarando que. Use esse cabeçalho.

Seu problema é ainda uma vaga um. Você está tentando proteger contra algo que você não pode.

Você pode adicionar a seguinte linha para a biblioteca cliente:

typedef struct INTERNAL_DATA *HandleType;

mas, se o nome / estrutura mudanças que você pode estar em algum maldade casting.

Tente modelos:

template <class T>
class Foo
{
    Foo(T h);
};

declaração para a frente é bom. Se você estiver indo para ponteiros de uso ou referências que você só precisa de uma declaração de classe (__INTERNAL_DATA) no espaço. No entanto, se você estiver indo para usar uma função membro ou um objeto que você terá de incluir o cabeçalho.

Outras dicas

Se o tipo está em uma biblioteca parte 3, em seguida, a grande vantagem de declaração para a frente (isolando reconstruções devido a mudanças no cabeçalhos) é efetivamente perdido.

Se você está preocupado com o tempo de compilação (é um cabeçalho considerável), então talvez você pode colocá-lo em um cabeçalho pré-compilado ou apenas incluir o cabeçalho relevante de uma biblioteca.

por exemplo. muitos cabeçalhos biblioteca parecer

// library.h
#include "Library/Something.h"
#include "Library/SomethingElse.h"
 typedef struct {} __INTERNAL_DATA, *HandleType;

Se ele é definido como aquele (todos em uma linha), então __INTERNAL DATA é tanto uma parte da interface pública como HandleType.

No entanto, eu não acho que __INTERNAL_DATA realmente existe. Mais do que provável, HandleType é realmente (internamente) um int. Esta definição estranho é apenas uma maneira de defini-lo de modo que é do mesmo tamanho que um int, mas distintas, de modo que o compilador dará um erro se você tentar passar um int onde você deveria passar um HandleType. O fornecedor da biblioteca poderia facilmente ter definiu como "int" ou "void *", mas desta forma podemos obter algum tipo de verificação.

Assim __INTERNAL_DATA é apenas uma convenção e não vai mudar.


UPDATE: O texto acima foi um pouco de um arroto mental, ... OK, __INTERNAL_DATA definitivamente não existe. Sabemos que isso é um fato, porque podemos ver a sua definição como um struct vazio. Eu estou indo supor que a biblioteca 3rd-party usos "C" ligação externa (sem nome managling), caso em que, basta copiar o typedef -. Ele vai ficar bem

Dentro da própria biblioteca, HandleType irá ter uma definição completamente diferente; talvez int, talvez "MyStruct struct {.......} *".

Se você realmente, realmente, realmente não quero expor _INTERNAL_DATA para o chamador então sua única opção real é usar typedef void * HandleType ; Em seguida, dentro de sua biblioteca que você pode fazer o que quiser, incluindo mudando toda a implementação de * HandleType.

Basta criar uma função auxiliar para acesso que dados real.

inline _INTERNAL_DATA* Impl(HandleType h) {
    return static_cast<_INTERNAL_DATA*>(h);
}

Eu não tenho certeza do que você está indo para, mas a seguir irá funcionar sem incluir o arquivo de cabeçalho real:

// foo.h
class Foo
{
    public:
    template<typename T>Foo(T* h) { /* body of constructor */ }
};

Mind você, você ainda tem que ter acesso aos membros públicos de __INTERNAL_DATA dentro do corpo do construtor.

edit:. como fora apontado por James Curran, a estrutura __INTERNAL_DATA não possui membros, para que ele possa ser usado, como acima, sem problemas

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top