O acesso a um modelo de classes base função tipo de ponteiro
-
21-08-2019 - |
Pergunta
Eu tenho uma classe que eu tenho desde que eu realmente não quero mudar, mas eu quero estender. Eu sou um padrão e modelo novato experimentar com um padrão Decorator aplicada a uma classe de modelo. classe de modelo contém um ponteiro-para-membro (se eu entendi a semântica corretamente) em outra classe. O ponteiro-para-membro é o desserializador de um istream XML. O tipo 'T' é o tipo de documento XML para ser desserializado.
template <typename T> class B {
public:
typedef std::auto_ptr<T> MYFUN(
std::istream&, const std::string&, const std::string& );
public:
B<T>( MYFUN* p );
private:
MYFUN *fptr;
std::string aString1;
std::string aString2;
};
Os typedef olhares estranhos para mim depois de ler http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.5 , e ainda assim esta classe parece funcionar bem como está. Não existem #defines adicionais no cabeçalho do arquivo fornecido, por isso este é um pouco misterioso para mim.
Agora eu tentar estendê-lo, como decorador, porque eu quero fazer um pouco mais de trabalho no objeto auto_ptr retornado por MyFun:
template <typename T>
class D : public class B<T>
{
D( B<T>::MYFUN *fPtr, B<T> *providedBase ); //compiler complaint
//Looks like B
private:
B* base_;
};
template <typename T>
D<T>::D( B<T>::MYFUN *p, B<T> *base ) //compiler complaint
:
B<T>::B( p ), base_(providedBase)
{ }
Ao tentar compilar isso, eu recebo uma queixa sintaxe nas duas linhas mostradas. Erro é algo como "esperado ')' em *". Não há nenhuma queixa sobre MyFun sendo indefinido.
Quando I re-definir o ponteiro-se membro em D com a mesma assinatura como em D, i.
//change MYFUN to NEWFUN in D)
typedef std::auto_ptr<T> MYNEWFUN(
std::istream&, const std::string&, const std::string& );
Isso funciona. Eu prefiro não ter que fazer isso para cada D / decorador eu poderia fazer de B. Tentei executar a typedef mais globalmente, mas não conseguiu obter o direito sintaxe devido ao parâmetro do modelo a ser indefinido.
Solução
O erro de compilação é devido ao fato de que o compilador não pode dizer que você está falando de um tipo.
Tente:
D( typename B<T>::MYFUN *fPtr, B<T> *providedBase );
e
template <typename T>
D<T>::D( typename B<T>::MYFUN *p, B<T> *base )
Veja: a secção de modelos do C ++ FAQ Lite para obter mais detalhes sobre por que isso é necessário, mas o resumo é que, devido à possibilidade de especialização de modelo, não há nenhuma maneira para que o compilador para ter certeza de que B<T>::MYFUN
está realmente se referindo a um tipo.
Outras dicas
A definição do typedef MyFun em B é feito com visibilidade privada. D não será capaz de acessá-lo. Se você alterá-lo para público protegido ou, não é então o trabalho?
template <typename T> class B {
protected:
typedef std::auto_ptr<T> MYFUN(
std::istream&, const std::string&, const std::string& );
...
};
O problema que vejo com isso é que B :: MyFun é a privada typedef.
Portanto, qualquer classe herdada não pode acessá-lo.
Alterar isso:
template <typename T> class B
{
public:
typedef std::auto_ptr<T> MYFUN( std::istream&, const std::string&, const std::string& );
public:
B<T>( MYFUN* p );
private:
MYFUN *fptr;
std::string aString1;
std::string aString2;
};