Pergunta

Eu tenho que correr em apuros tentando implementar funcionalidade para serialização de algumas classes no meu jogo. Eu armazenar alguns dados em um arquivo de texto simples e eu quero ser capaz de salvar e carregar de / para ele. Os detalhes deste, no entanto, são irrelevantes. O problema é que eu estou tentando fazer com que cada objeto que é interessante para o salvar o arquivo para ser capaz de serializar si. Por isso eu tenha definido uma interface ISerializable, com declarações puramente virtuais do operador << e operador >>.

A classe de hierarquia é algo como isto

              -> GameObject -> Character -> Player ...
ISerializable               -> Item -> Container ...
              -> Room ...

Isto significa que há muitas situações possíveis para a serialização de objetos de diferentes classes. Recipientes, por exemplo, deve chamar operador << em todos os itens contidos.

Agora, desde que operator >> é virtual, eu pensei que se eu queria serialize algo que implementa a funcionalidade definida na ISerializable eu poderia apenas fazer algo como

ostream & Player::operator<<(ostream & os){
    Character::operator<<(os);
    os << player_specific_property 1 << " " 
       << player_specific_property 2 << "...";
    return os;
}

e

ostream & Character::operator<<(ostream & os){
    GameObject::operator<<(os);
    os << character_specific_property 1 << " " 
       << character_specific_property 2 << "...";
    return os;
}

mas eu aprendi rapidamente que esta primeira tentativa foi ilegal. O que eu estou pedindo aqui é como faço para contornar este ?

Eu não me sinto como a implementação de uma função manualmente para cada classe. Eu acho que eu estou procurando algo como a funcionalidade super de Java.

Qualquer ajuda é apreciada.

- COMENTÁRIO DO EDIT ------------

Tudo bem, última vez que eu estava com pressa quando eu estava escrevendo a questão. O código agora é mais como era quando eu tentei para compilá-lo. Fixei a questão eo problema que tive não estava relacionado com a pergunta. Tenho vergonha de dizer que foi causado por um erro na esteira de uma grande refatoração do código, eo fato de que o operador não foi implementado em todas as classes base.

Muitos agradecimentos para as respostas no entanto!

Foi útil?

Solução

O problema não está na sua tentativa de chamar uma função virtual não virtualmente. O problema é esta linha: os = Character::operator<<(os);. Essa é uma atribuição, mas std::ostream não tem um operator=.

Você não precisa a atribuição de qualquer maneira. O fluxo retornado é o mesmo fluxo como o fluxo de você passar. A única razão pela qual ele é retornado é assim que você pode encadear-los.

Assim, a correção é apenas para alterar o código para

ostream & Player::operator<<(ostream & os){
    Character::operator<<(os);
    os << player_specific_property 1 << " " 
       << player_specific_property 2 << "...";
    return os;
}

Outras dicas

Isto não é como a sobrecarga de operador << para obras ostream. O operador da mão esquerda é um ostream (daí você tem que sobrecarregá-lo como uma função gratuita) e o operador do lado direito é o seu objeto (que é por isso que o mecanismo virtual não seria facilmente trabalho.

Eu suponho que você poderia tentar:

class Base
{
    //...
    virtual std::ostream& output(std::ostream&) const;
};

std::ostream& operator<< (std::ostream& os, const Base& obj)
{
    return obj.output(os);
}

Agora uma classe derivada naturalmente pode chamar o método de seu pai (s) de saída:

class Derived: public Base
    //...
    virtual std::ostream& output(std::ostream& os) const
    {
        Base::output(os);
        return os << my_specific_data;
    }
};
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top