2009-06-04 6 views
10

J'ai vu le code comme suit souvent dans un code C++ Je suis à la recherche:Quel est le but de typedefing une classe en C++?

typedef class SomeClass SomeClass; 

Je suis perplexe quant à ce que cela atteint en réalité. Il semble que cela ne changerait rien. Que font les typedef comme ça? Et si cela fait quelque chose d'utile, cela en vaut-il la peine?

+4

peut-être que vous devriez demander à cette personne? plutôt que de demander à tout le monde, mais cette personne. – DevinB

+0

Je voulais obtenir un consensus sur le fait que cela en valait la peine plutôt que sur l'explication d'une personne. –

+0

Et le gars avait en réalité tort. "non-tag cache le nom de tag en C++" - ni vrai en C, ni vrai en C++. Pour un peu d'inspiration, lisez ce rapport de défaut http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#407 –

Répondre

7

Voir cette réponse à une question connexe. Il est une longue citation d'un article qui explique Dan Saks cette question aussi clairement que tout ce que je suis venu à travers:

Difference between 'struct' and 'typedef struct' in C++?

La technique peut prévenir les problèmes réels (bien que des problèmes certes rares). C'est une assurance bon marché - c'est zéro coût à l'exécution ou dans l'espace de code (le seul coût est les quelques octets dans le fichier source), mais la protection que vous obtenez est si petite qu'il est rare de voir quelqu'un l'utiliser régulièrement. J'ai un extrait de "nouvelle classe" qui inclut le typedef, mais si je code réellement une classe à partir de zéro sans utiliser l'extrait, je ne m'inquiète presque jamais (ou est-ce que je me souviens?) D'ajouter le typedef.

Je dirais que je suis en désaccord avec la plupart des avis donnés ici - il vaut la peine de mettre ces typedefs, mais ne suffit pas que je donnerais tout le monde (y compris moi-même) le chagrin de ne pas les mettre dans

.

on m'a demandé un exemple de comment ne pas avoir un nom de classe typedef peut entraîner un comportement inattendu - est ici un exemple soulevé plus ou moins de l'article Saks:

#include <iostream> 
#include <string> 

using namespace std; 

#if 0 // change to #if 1 to get different behavior 
     // imagine that this is buried in some header 
     // and even worse - it gets added to a header 
     //  during maintenance... 
string foo() 
{ 
    return "function foo... \n"; 
} 
#endif 

class foo 
{ 
public: 
    operator string() { 
     return "class foo...\n"; 
    } 
}; 

int main() 
{ 
    string s = foo(); 

    printf("%s\n", s.c_str()); 
    return 0; 
} 

Lorsque la déclaration de fonction est faite visible, le comportement du programme change silencieusement car il n'y a pas de conflit de nom entre la fonction foo et la cla ss foo. Cependant, si vous incluez un "typedef class foo foo;", vous obtiendrez une erreur de compilation au lieu d'une différence de comportement silencieuse.

+0

Vous devez le faire beaucoup de choses pour que cela se produise que je suis tenté de dire que vous le méritez! Le numéro un fournirait des conversions au lieu d'utiliser des fonctions nommées (toujours un non-non, à mon humble avis). –

+2

Les opérateurs de conversion peuvent être un non-non, mais ils ne sont pas du tout rares. De toute façon, je ne vais pas discuter du point «tant de choses doivent se tromper». Comme je l'ai dit, ce n'est pas quelque chose que j'insiste dans mon code ou celui de quelqu'un d'autre. Mais je voulais expliquer pourquoi c'est dans le code OP (c'était la question après tout), et souligner que le typedef n'a aucun coût et ne pose aucun problème. En fait, cela fait que les compilateurs agissent un peu plus comme les gens l'attendent - bien que j'ai été surpris par le comportement de certains compilateurs à l'extrait d'Adam. Je pense que le document lié par litb est instructif à cet égard. –

+0

C'est vraiment intéressant. les réponses que j'ai eues à cette question me rendent heureux d'avoir posé cette question ici. –

0

Il semble que le commentaire essaie de dire que le typedef rend le symbole SomeClass global d'une manière qui empêche quiconque de déclarer un objet local avec le même nom qui cache la SomeClass d'origine.

J'ai essayé ceci avec VC6 (pas un vrai compilateur C++ je sais, mais le meilleur que j'ai ATM), et il ne semble pas faire beaucoup. SomeClass est toujours masqué par une déclaration locale portant le même nom. Peut-être change-t-il le contenu d'un message d'erreur pour un compilateur afin de le rendre plus utile.

-2

Je comprends le concept des différents espaces de noms que les balises et les identificateurs vivent, mais est-ce vraiment vaut même la peine de taper?

n °

+6

(-1) Absolument aucune explication ou raison. Je pourrais tout aussi bien avoir écrit "Oui". et la seule différence aurait été la réputation. – DevinB

+0

Vous n'aimez pas ma réponse (il, après tout, exposé le raisonnement), écrivez le vôtre. –

0

Il me semble que votre collègue peut-être pas entièrement diplômé de C.

En C, si vous déclarez struct foo {int a;};, vous n'avez pas tout ce que vous pouvez appeler simplement foo , mais plutôt struct foo. Par conséquent, il est assez commun de typedef struct foo comme foo.

Cela a été modifié en C++, pour des raisons qui devraient être assez évidentes.

+1

C'est possible, mais je n'appellerais pas vraiment le comportement de C "nom caché". –

20

Il empêche le code comme celui-ci de la compilation:

class SomeClass { ... }; 
int SomeClass; 

Ceci est parfaitement légal C++, mais il est terribles. Si vous faites cela, alors toutes les références à un SomeClass nu font référence à la variable. Pour faire référence à la classe, vous devez indiquer explicitement class SomeClass à chaque utilisation. Si vous créez un typedef:

class SomeClass { ... }; 
typedef class SomeClass SomeClass; 
int SomeClass; 

Ensuite, les drapeaux du compilateur comme une erreur la définition de int SomeClass, comme cela devrait être à juste titre.

+0

Votre deuxième exemple compile pour moi (VC2005). –

+3

Problème avec VC++ alors - il ne devrait pas compiler. –

+0

Intéressant, il fonctionne réellement avec un compilateur que j'utilise (et pas avec MSVC) – Dolphin

0

Compilateur vraiment cassé ou quelqu'un ne sachant pas ce qu'ils font, ou alors je pense.

+0

Ou quelqu'un connaissant quelque chose que beaucoup de gens ne connaissent pas ... –

6

Adam a fourni la bonne raison de le faire, mais en ce qui concerne votre question "Vaut-il la peine", je donnerais un "Non!" Retentissant.Le code de problème possible:

class SomeClass { ... }; 
int SomeClass; 

sera pris quand un peu plus tard quelqu'un dit:

SomeClass sc; 

Il est vrai que le compilateur pointera sur la ligne « mauvais », mais ce genre de chose arrive si rarement (Je ne pense pas que je l'ai jamais vu en code réel) qu'il ne peut pas justifier une forêt de typedefs presque superflu.

+0

Merci d'avoir répondu à cette question, c'est ce que je voulais vraiment savoir. Je n'avais jamais vu ça avant, alors j'avais le sentiment que ça ne vaudrait pas le coup. –

+0

Si vous omettez le typedef, il se peut que vous n'ayez pas toujours d'erreur, mais il est vrai que les situations seraient rares. Une fonction avec le même nom qu'une classe peut cacher quelque chose qui serait autrement un constructeur de classe. –

+0

Pourriez-vous poster un exemple de ceci - je ne peux pas visualiser comment cela serait possible. –

Questions connexes