2 votes

Est-il possible, d'une manière ou d'une autre, de fournir un opérateur de flux en ligne dans une classe (c'est-à-dire sans ami) ?

Tout d'abord, je tiens à préciser que j'ai lu la solution. {fourni ici} qui stipule que

Notez que les opérateurs de flux de sortie ne sont généralement pas des fonctions membres. (En effet, pour que les opérateurs binaires soient des fonctions membres, ils doivent être membres du type de leur argument de gauche. Or, il s'agit d'un flux, et non de votre propre type. Il y a l'exception de quelques surcharges de operator<<() pour certains modules intégrés, qui sont membres de la classe de flux de sortie).

Voici mon problème. Je supprimais une bibliothèque d'une grande application. La bibliothèque était censée condenser toutes ses fonctionnalités utiles dans un fichier d'en-tête.

L'une des classes de ce fichier d'en-tête doit avoir une surcharge de l'opérateur stream <<. Je ne sais pas comment faire sans utiliser une fonction amie, et si j'utilise une fonction amie, je ne peux pas tout faire dans un fichier d'en-tête parce que j'obtiendrais de multiples erreurs de définition.

Existe-t-il donc une astuce - peut-être un jeu avec les foncteurs, les wrappers, ou autre, qui me permettrait d'écrire une définition pour la surcharge de l'opérateur pour << dans ma classe afin d'éviter ce problème ?

4voto

ildjarn Points 38377
class SomeClass
{
    friend std::ostream& operator <<(std::ostream& os, SomeClass const& sc)
    {
        // impl
        return os;
    }
};

Les définitions de fonctions fournies en ligne à l'intérieur de la définition de la classe sont implicitement marquées inline et, par conséquent, ne provoquera pas d'erreurs de l'éditeur de liens à définitions multiples.

Vous pouvez également fournir la définition hors ligne et la marquer explicitement inline ce qui permet d'éviter les erreurs de l'éditeur de liens à définitions multiples :

class SomeClass
{
    // unnecessary if operator<< doesn't need access to non-public members
    friend std::ostream& operator <<(std::ostream&, SomeClass const&);
};

inline std::ostream& operator <<(std::ostream& os, SomeClass const& sc)
{
    // impl
    return os;
}

2voto

Joe Gauterin Points 9526

Si j'utilise une fonction ami, je ne peux pas tout faire dans un en-tête, car j'obtiendrais plusieurs définitions. car j'obtiendrais de multiples erreurs de définition.

Marquez la fonction amie en ligne, vous n'obtiendrez pas d'erreurs de définition multiples.

1voto

Mark B Points 60200

Non, la sémantique du fonctionnement de la surcharge des opérateurs vous en empêche.

Mais rien ne dit qu'une fonction amie ne peut pas également être (qualifiée de) en ligne, auquel cas vous n'avez pas à vous soucier des définitions multiples : C'est le compilateur qui s'en charge.

Je dirais que l'une des méthodes habituelles pour mettre en œuvre le streaming est d'utiliser une fonction print publique (éventuellement virtuelle) qui prend un stream& et de l'appeler à partir d'un utilisateur non membre et non ami. operator<< qui pourrait facilement être intégré dans votre en-tête.

0voto

Vous pouvez avoir une classe de base avec quelque chose comme void streamout(std::ostream& out) une fonction membre virtuelle et un opérateur ami (si vous devez le garder privé, mais je ne vois pas pourquoi) qui n'est pas membre. Ensuite, pour toutes les classes dérivées, vous devrez implémenter une fonction membre, ce que vous semblez vouloir.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X