2010-09-28 9 views
10

Je suis en train de concevoir une classe Buffer dont le but est de représenter un morceau de mémoire.void * ou char * pour la représentation du tampon générique?

Mon tampon sous-jacent est un char* (enfin, un boost::shared_array<char> en fait, mais cela n'a pas vraiment d'importance).

Je suis coincé à décider quel prototype choisir pour mon constructeur:

Dois-je aller avec:

Buffer(const void* buf, size_t buflen); 

Ou avec:

Buffer(const char* buf, size_t buflen); 

Ou autre chose?

Qu'est-ce qui est habituellement fait, et pourquoi?

+0

@Luca Matteis: J'ai l'intention de fournir un partage implicite de la mémoire. Mais c'est tout à fait hors sujet. – ereOn

+1

Il ya une transmogrification malheureuse - incitée par Unicode - en ce que 'char' devient un synonyme de' octet' et a peu à voir avec "caractère". Cette question est symptomatique de ce changement; J'ai été tenté de "typedef char octet;" parfois pour rendre le code moins trompeur. – msw

+0

@msw: Outre la compatibilité de type avec les littéraux de chaîne, existe-t-il une raison d'utiliser "char", par opposition à "char signé" ou "char signé"? Cela me semble un type plutôt inutile. – supercat

Répondre

11

L'interface de l'API est plus claire pour l'utilisateur, si le tampon a le type void *, et la chaîne a le type char *. Comparez les définitions de fonctions memcpy et strcpy.

+1

Effectivement, c'est logique. – ereOn

6

Je préférerais char*, parce que pour moi personnellement il joue mieux d'être "un tampon". void* ressemble plus à "un pointeur vers je ne sais quoi". D'ailleurs, c'est ce que votre sous-jacent est, de toute façon.

+15

Un "void *" n'est pas un "pointeur vers je ne sais pas où", c'est un "pointeur vers je ne sais pas quoi" :-) – paxdiablo

+0

@pax: ouais, je suppose que ça sonne mieux (même si au départ je pensé que cela semble équivalent), donc je l'ai changé à "quoi" –

+0

Mais un tampon générique est exactement cela: un tampon pour "je ne sais pas quoi". – 12431234123412341234123

14

Pour le constructeur et les autres fonctions API, l'avantage de void* est qu'il permet à l'appelant de passer dans un pointeur vers n'importe quel type sans avoir à effectuer un cast inutile. S'il est logique que l'appelant puisse passer dans n'importe quel type, alors void* est préférable. Si cela n'a vraiment de sens que pour l'appelant de pouvoir passer en char*, alors utilisez ce type.

+0

Je suis d'accord avec vous :) – vulkanino

8

En général, j'utilise unsigned char comme structure sous-jacente (je ne veux pas que la signature mette en erreur mon tampon car je sais quelle raison). Cependant, je TypeDef habituellement il:

typedef unsigned char byte; 

Et puis parler comme byte* qui transmet parfaitement le sens à mon avis, mieux que ce soit char* ou void* au moins.

+1

Je ne peux pas +1 assez dur. Cela soulage tous ces bugs avec 'char' comme' char buf [42]; ... si (buf [i] == 0xFF) // * jamais vrai * ' – Thanatos

6

Je recommanderais uint8_t, qui est défini dans stdint.h. C'est fondamentalement la même chose que le "typedef unsigned char byte"; que d'autres ont recommandé, mais il a l'avantage de faire partie de la norme C. Comme pour void *, je ne l'utiliserais que pour le polymorphisme. c'est à dire. J'appellerais seulement quelque chose un pointeur de vide si je ne savais pas encore quel genre de chose il pointerait. Dans votre cas, vous avez un tableau d'octets, donc je l'étiqueterais en utilisant uint8_t * comme type.

2

Je préfère unsigned char * ou uint8_t * pour les implémentations de tampon, puisque void * a la restriction gênante que vous ne pouvez pas effectuer de maths de pointeur dessus. Donc, si vous voulez traiter certaines données à un certain décalage par rapport à la mémoire tampon, ou juste casser votre mémoire tampon en morceaux ou autre chose, vous êtes quand même obligé de passer à un autre type pour faire le calcul.

Je préfère unsigned char * ou uint8_t * sur plaine char * en raison de la special rules en ce qui concerne l'aliasing et char *, qui a le potentiel de pessimize sérieusement des boucles travaillant sur vos tampons.