OVH Cloud OVH Cloud

template et const

22 réponses
Avatar
Fabien SK
Bonjour,

Je désire écrire une classe permettant de manipuler un sous-ensemble
d'un buffer texte. Cette classe n'aura comme donnée membre que le
pointeur sur la partie du buffer et la taille du buffer à manipuler.
Exemple:

class InBuffField
{
public:
InBuffField(char *pbuff, size_t len);

char* Get();
size Len()const;
void Trim(char c=' ');
bool Compare(InBuffField &other)const;
bool CompareTrim(InBuffField &other)const;
// [...]
private:
char *m_pBuff;
size_t m_Len;
};

char *pbuff = "TOTO 12345 TATA";
InBuffField field(pbuff, 6);
field.TrimRight();
std::cout << field.Length() << std::endl; // affiche '4'
std::cout.write(field.Get(), field.Length());

Mon problème est que je veux supporter dans cette classe à la fois les
pointeurs vers des "char*" et des "const char*". La version avec "const
char*" n'aurait donc pas accès à des méthode telles que "Replace".

Je dois donc décider d'un type pour "m_pBuff". Je ne vois pas comment
faire, à part en faisant une classe template pouvant prendre comme type
"char" ou "const char". Par contre après, ça va me poser des problèmes
pour mes méthodes "Compare" car elles vont devoir comparer des objets de
type:
- InBuffField<char>
- InBuffField<const char>

J'ai pensé à la conversion automatique (fonction membre):

operator InBuffField<const _CH>()const
{
return InBuffField<const _CH>(m_pBuff, m_Len);
}

Mais je sens que ça va me mener à des effets aussi indésirables
qu'inattendus.

Si vous avez une idée de design, je suis preneur.
Merci de votre attention

Fabien

10 réponses

1 2 3
Avatar
Gabriel Dos Reis
Fabien SK <fabsk+ writes:

| > Mais qu'en est-il finalement de l'affectation initiale :
| > char * str = "..." ;
| > Je pensais comme Fabien (Le Lez) que cela était interdit. Il me
| > semble que cela était légal en C, et encore, plus en C99, mais pas en
| > C++. Juste ?
| > --drkm
|
| g++ ne bronche pas avec "-Wall -pedantic -ansi" :-(

GCC ne bronche pas encore sur toutes les features deprecated -- là je
crois que Fabien doit etre aux anges.

-- Gaby
Avatar
Gabriel Dos Reis
Fabien SK <fabsk+ writes:

| Fabien LE LEZ wrote:
| > On Thu, 14 Aug 2003 15:46:45 +0200, Fabien SK <fabsk+
| > wrote:
| >
| >> j'aurais trouvé plus simple que les chaînes soientt toujours des
| >> "const char*"
| > Chez moi, une chaîne est toujours "const char*" ou "std::string" :-)
|
| Ah si la norme et les compilateurs étaient comme toi... :-) Ils
| refuseraient:
|
| "toto"[0] = 'a';

Ce n'est pas valide en C++. Et tu te fais insulter par GCC.

-- Gaby
Avatar
Fabien SK
Gabriel Dos Reis wrote:

| Ah si la norme et les compilateurs étaient comme toi... :-) Ils
| refuseraient:
|
| "toto"[0] = 'a';

Ce n'est pas valide en C++. Et tu te fais insulter par GCC.

-- Gaby


Au temps pour moi :-( Je confondais avec le tout aussi mauvais (ma
mémoire me joue des tours):

int main(int argc, char *argv[])
{
char *ptr = "toto"; // deprecated :-)
ptr[0] = 'a'; // je sais comportement indéfini
// mais nul avertissement par le compilo

return 0;
}

Avatar
Fabien LE LEZ
On 14 Aug 2003 16:39:19 +0200, Gabriel Dos Reis
wrote:

features deprecated -- là je
crois que Fabien doit etre aux anges.


;-)

Au fait, sois précis -- nous sommes maintenant deux Fabien ici ;-)


--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Avatar
Fabien SK
Fabien LE LEZ wrote:

features deprecated -- là je
crois que Fabien doit etre aux anges.


Au fait, sois précis -- nous sommes maintenant deux Fabien ici ;-)


Je peux m'appeler Jean-Robert par commodité, si tu veux.


Avatar
Fabien LE LEZ
On Thu, 14 Aug 2003 16:56:43 +0200, Fabien SK <fabsk+
wrote:

Je peux m'appeler Jean-Robert par commodité, si tu veux.


Pourquoi "Jean-Robert" ? Parce que "Dominique" ça porterait à
confusion ?


--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Avatar
Christophe Lephay
"Fabien LE LEZ" a écrit dans le message de
news:
On Thu, 14 Aug 2003 16:56:43 +0200, Fabien SK <fabsk+
wrote:

Je peux m'appeler Jean-Robert par commodité, si tu veux.


Pourquoi "Jean-Robert" ? Parce que "Dominique" ça porterait à
confusion ?


D'un autre coté, je trouve que Jean-Robert donne un peu plus d'indication
sur l'intention du programmeur. Il est peu probable que la personne qui
signe Jean-Robert signe là de son vrai nom (même si on peut envisager des
cas malheureux(*), heureusement exceptionnels, où cette propriété ne serait
pas vérifiée).

Je trouve que Jean-Robert, par son aspect improbable, montre mieux qu'il
s'agit d'une commodité sémantique...

Chris

(*) malheureux parce que c'est pas toujours agréable de trop ressembler à un
cliché ou à une caricature


Avatar
drkm
Fabien LE LEZ writes:

On 14 Aug 2003 15:24:27 +0200, drkm wrote:

Mais qu'en est-il finalement de l'affectation initiale :

char * str = "..." ;

Je pensais comme Fabien (Le Lez) que cela était interdit. Il me
semble que cela était légal en C, et encore, plus en C99, mais pas
en C++. Juste ?


Je ne suis pas très sûr de moi sur la légalité de la chose. Ce qui
est certain, c'est la la modification du tableau est interdit.


Tu parles bien de la zone référencée par le pointeur, et non de la
version avec initialisation de tableau (comme tu l'as proposée) ? Car
c'est justement l'avantage d'utiliser un tableau : les modifications
sont permises.

Je ne pense pas -- à confirmer -- que la norme impose une manière
spécifique de stocker une chaîne de caractères litérale. Je pense
néanmoins qu'une implémentation classique est de placer toutes ces
chaînes litérales dans un segment de données, qui peut être en lecture
seule surveillée par l'OS. Et là, BOUM !

Si l'on arrive néanmoins à modifier une chaîne litérale, au travers
d'un pointeur non-const [*], il est possible que cette chaîne
aparaisse à plusieurs endroits dans le programme et que le litéral
n'est alors plus égal à ce qu'il valait dans le code source (!).

[*] Abus de langage ; plutôt pointeur « vers non-const ».

Ne pas mettre le "const" à "char const*" est donc de l'obfuscation.


Yep. Puis c'est dangereux. Puis je ne pense pas que cela soit
légal. Puis c'est déroutant ; si je vois une telle chose, je ne sais
pas si c'est une erreur de distraction, ou si l'auteur veut quelque
chose de spécial.

--drkm


Avatar
drkm
Gabriel Dos Reis writes:

drkm writes:

| Mais qu'en est-il finalement de l'affectation initiale :

| char * str = "..." ;

deprecated.


Donc légal ?!? J'étais persuadé que ce n'était légal que dans les C
ancestraux, pré-C89, et certainement plus en C++98.

Comme quoi ...

--drkm, cherchant des repères, quelque chose de tangible à laquelle
s'accrocher.

Avatar
Gabriel Dos Reis
drkm writes:

| Je ne pense pas -- à confirmer -- que la norme impose une manière
| spécifique de stocker une chaîne de caractères litérale.

à part que c'est une lvalue et un tableau ?

[...]

| > Ne pas mettre le "const" à "char const*" est donc de l'obfuscation.

C'est assez courant en C.

-- Gaby
1 2 3