79 votes

Pourquoi ne puis-je pas hériter de int en C ++?

J'aimerais être capable de faire cela:

class myInt : public int
{

};

Pourquoi ne puis-je pas?

Pourquoi voudrais-je? Plus de la frappe. Par exemple, j'ai pu définir deux classes intA et intB, ce qui laisse-moi faire intA + intA ou intB + intB, mais pas intA + intB.

"Ints ne sont pas des classes." Et alors?

"Ints n'ont pas de données sur les membres." Oui, ils le font, ils ont 32 bits, ou quoi que ce soit.

"Ints n'ont pas de fonctions membres." Eh bien, ils ont tout un tas d'opérateurs comme + et -.

90voto

Jerry Coffin Points 237758

Neil commentaire est très précis. Bjarne mentionné en considérant et en rejetant cette possibilité1:

L'initialiseur de syntaxe utilisée pour être illégal pour les types intégrés. Pour permettre c', j'ai introduit la notion que construit-dans les types de constructeurs et les destructeurs. Par exemple:

int a(1);    // pre-2.1 error, now initializes a to 1

J'ai envisagé d'étendre cette notion à permettre la dérivation de classes intégrées et une déclaration explicite de les opérateurs de type intégré. Cependant, Je me suis retenu.

Permettant la dérivation à partir d'un intn'a pas effectivement donner un programmeur C++ rien de manière significative de nouveau par rapport à avoir un int membre. C'est principalement parce que l' int n'ont pas toutes les fonctions virtuelles pour les dérivés classe remplacer. Plus sérieusement cependant, le C des règles de conversion sont donc chaotique que de prétendre qu' int, short, etc., sont bien comportés les classes ordinaires est pas d'aller travailler. Ils sont soit C compatible, ou qu'ils obéir à la relativement bien comportés C++ règles pour les classes, mais pas les deux.

Autant que le commentaire de la performance justifie pas faire int une classe, c'est (au moins pour la plupart) faux. En Smalltalk, tous les types sont les classes-mais près de toutes les implémentations du langage Smalltalk ont optimisations de sorte que la mise en œuvre peut être essentiellement identique à la façon dont vous ferais un non-class type de travail. Par exemple, le smallInteger classe représente 15 bits entier, et le '+' message est codé en dur dans la machine virtuelle, de sorte que même si vous pouvez tirer de smallInteger, il donne toujours des performances similaires à un type (bien que Smalltalk est assez différent de C++ qui dirigez l'exécution des comparaisons sont difficiles et il est peu probable beaucoup de sens).

Edit: un peu c'est "perdu" dans le langage Smalltalk mise en œuvre de smallInteger ne serait probablement pas nécessaire en C ou C++. Smalltalk est un peu comme Java -- lorsque vous "définir un objet" vous êtes vraiment seulement la définition d'un pointeur vers un objet, et vous devez allouer dynamiquement un objet pour qu'il point. Ce que vous manipuler, transmettre à une fonction comme paramètre, etc., c'est toujours juste le pointeur, pas de l'objet lui-même.

C'est pas comment smallInteger est mis en œuvre -- il y a dans son cas, ils ont mis la valeur de l'entier directement dans ce qui serait normalement le pointeur. Pour faire la distinction entre un smallInteger et un pointeur, ils ont la force de tous les objets alloués à même les limites d'octets, de sorte que le LSB est toujours clair. Un smallInteger a toujours le LSB ensemble.

La plupart de ce qui est nécessaire, cependant, parce que Smalltalk est dynamiquement typé, il doit être en mesure de déduire le type en regardant la valeur elle-même, et smallInteger est essentiellement l'aide que LSB type de balise. Étant donné que C++ est statiquement typé, il n'y a pas besoin d'en déduire le type de la valeur, de sorte que vous ne serait probablement pas besoin de perdre un peu.

1 Dans La Conception et l'Évolution de C++, §15.11.3.

52voto

David Lively Points 16026

Int est un type ordinal, pas une classe. Pourquoi voudriez-vous?

Si vous avez besoin d'ajouter des fonctionnalités à "int", envisager la construction d'un agrégat de classe qui a un champ de type entier, et les méthodes qu'exposer ce que des fonctionnalités supplémentaires que vous avez besoin.

Mise à jour

@OP "Ints ne sont pas des classes" alors?

L'héritage, le polymorphisme et l'encapsulation sont les clés de voûte de la conception orientée objet. Aucune de ces choses s'appliquent à ordinale types. Vous ne pouvez pas hériter d'un int, parce que c'est juste un tas d'octets et n'a pas de code.

Entiers, caractères, et d'autres ordinale types n'ont pas de méthode de tables, donc il n'y a aucun moyen d'ajouter des méthodes ou de les remplacer, ce qui est vraiment le cœur de l'héritage.

24voto

jalf Points 142628

Pourquoi voudrais-je? Plus de la frappe. Par exemple, j'ai pu définir deux classes de l'intA et intB, qui permettez-moi de faire l'intA+intA ou intB+intB, mais pas l'intA+intB.

Qui n'a pas de sens. Vous pouvez faire tout cela sans hériter de quoi que ce soit. (Et, d'autre part, je ne vois pas comment vous pourriez peut-être obtenir l'aide de la succession.) Par exemple,

class SpecialInt {
 ...
};
SpecialInt operator+ (const SpecialInt& lhs, const SpecialInt& rhs) {
  ...
}

Remplissez les espaces vides, et vous avez un type qui permet de résoudre votre problème. Vous pouvez le faire SpecialInt + SpecialInt ou int + int, mais SpecialInt + int ne compile pas, exactement comme vous le vouliez.

D'autre part, si l'on prétendait que l'héritage de int était légal, et notre SpecialInt dérivés de int, alors SpecialInt + int serait de compiler. Héritant serait la cause du problème exact que vous voulez éviter. Pas hériter évite le problème facilement.

"Ints n'ont pas de fonctions membres." Eh bien, ils ont tout un tas d'opérateurs comme les + et les -.

Ceux-là ne sont pas des fonctions de membre du bien.

13voto

Stephen C. Steel Points 2869

Si le PO veut vraiment comprendre pourquoi C ++ est ce qu'il est, il devrait alors se procurer un exemplaire du livre de Stroustup "La conception et l'évolution du C ++". Il explique la raison de cela et de nombreuses autres décisions de conception dans les débuts de C ++.

10voto

Mason Points 1978

Parce que l'int est un type natif, et non pas une classe

Edit: déplacement de mes commentaires dans ma réponse.

Il s'agit de la C du patrimoine et ce qui, exactement, primitives représentent. Une primitive de c++ n'est qu'une collection d'octets qui ont peu de sens, sauf pour le compilateur. Une classe, d'autre part, a une table de fonction, et une fois que vous commencez à aller en bas de la succession et de l'héritage virtuel chemin, alors vous avez une vtable. Aucune de ce qui est présent dans un primitif, et en le faisant vous présenter: a) pause beaucoup de code c qui suppose un int est de 8 octets seulement, et b) de rendre les programmes prennent beaucoup plus de mémoire.

Penser d'une autre manière. int/float/char n'ont pas de membres de données ou de méthodes. Pensez à les primitives comme les quarks - ils sont les blocs de construction que vous ne pouvez pas subdiviser, vous les utiliser pour faire des choses plus importantes (toutes mes excuses si mon analogie est un peu hors, je ne connais pas assez la physique des particules)

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