360

Nil : les références java, perso je vois ça comme des HANDLE de nos TIs ^^

361

Brunni (./351) :
Ben c'est comme si en C tu fais:
char *str1 = "Hello", *str2 = str1;
str2[1] = 'u';
printf("%s", str1);    // Hullo
C'est un piège lié aux références en soi.

Effectivement. Mais justement, avec QString, tu n'as pas ce problème:
QString str1 = "Hello", str2 = str1;
// À cet endroit, une seule copie de la chaîne existe.
str2[1] = 'u';
// et paf, copy-on-write, on a maintenant str1 qui vaut "Hello", str2 qui vaut "Hullo"
printf("%s", str1);    // Hello

smile

Et le plus cool, c'est que depuis Qt 4.0.0, tout ceci est thread-safe (au même titre que par exemple int l'est: on peut toujours avoir des conflits si les 2 threads essaient d'utiliser str1, mais avoir str1 dans un thread et str2 dans un autre, les 2 partageant les données, est sans danger, le copy-on-write est thread-safe).
Uther (./359) :
Mais attention quand on déclare une référence final, ca veux dire qu'on ne peut la modifier, mais on peut toujours modifier les attributs de l'objet, il n'y a pas d'équivalent aux méthodes const. Encore une simplification : c'est moins puissant que le const mais réduit également la complexité du concept.

C'est surtout une recette pour bogues non détectables, d'autant plus qu'il n'y a pas de copy-on-write. roll
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

362

Ben nan, le principe des références, c'est que toutes les copies des références pointent vers le même objet, et que les modifications faites au travers d'une référence impactent les autres références.

Le copy-on-write, c'est plutôt une optimisation qui utilise des références en interne alors que tu penses utiliser des valeurs. Dans ton exemple, les QString se comportent exactement comme des objets "valeurs" et pas comme des références. Si tu n'en avais pas parlé, jamais j'aurais su que c'était des références.
copy-on-write -> sémantique valeurs et pas références, donc pas comparable avec ce que fait java
avatar

363

Je vois pas quel problème pose le code de Brunni en fait.
Où est-il spécifié qu'on a voulu construire une deuxième string et copier la première dedans ? On a deux pointeurs vers une seule string, le comportement décrit est le comportement attendu, je ne vois pas ce qui et choquant...
Il parle ici de char*, donc de chaine "style C", pas d'objets se recopiant, comme visiblement les QString.

Qu'est-ce que je capte pas dans votre discussion ? confus

364

aze (./362) :
Le copy-on-write, c'est plutôt une optimisation qui utilise des références en interne alors que tu penses utiliser des valeurs.

Oui, c'est pour ça que c'est bien, surtout si on compare avec le "tout est référence" style Java où tu utilises une syntaxe de valeurs alors que tu as en fait une référence, ce qui induit des erreurs. Avec Qt, l'API utilise des pointeurs quand il y a une sémantique par référence (QObject) et du copy-on-write quand il y a une sémantique par valeur (classes de données, genre QString), donc on ne risque pas de se tromper.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

365

c'est bien, mais je ne connaissais pas avant que tu en parles

Je n'ai pas l'impression que boost en propose (en tous cas, je n'ai pas trouvé). Niveau implémentation, ils doivent avoir un operateur -> const et un non-const qui copie l'objet je suppose ?
avatar

366

./364 Euh justement si c'est du tout référence tu n'as pas de risque de te planter, et ça simplifie la syntaxe parce que tu n'as pas besoin d'étoiles partout.
Encore une fois, en principe en prog objet la "valeur" n'a pas vraiment raison d'exister puisqu'un objet est une entité! J'ai l'impression que tu accordes une trop grande importance à cette notion parce que tu mélanges les paradigmes, tout comme C++.
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

367

Mais t'as pas pris un mauvais exemple avec ton char* ? C'est pas un objet justement, et tu faisait explicitement une manipulation de pointeurs dessus ? Bref, je comprends pas, pas grave.


ps -> si on devait forker ce topic avec vos trolls sur le java et les références, ça ferait 95% des posts à dégager dont 99.9% de ceux de Brunni. Mais bon, on dira que tant que j'ai mes réponses j'ai pas à me plaindre ? :/

368

Voilà. Et malgré mes trolls, des réponses je t'en ai données ^^
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

369

Tu peux comprendre que ça peut me mélanger un minimum les pinceaux : essayer de comprendre ce qu'on me répond, et essayer de comprendre ce que vous me dites. Faut faire le tri, pas évident quand on patauge.

370

Ouep, et je pense que c'est utile étant donné que le C++ est tellement riche que tu as 100 manières de faire les choses, et certaines sont adaptées à des cas spéciaux (voire sont dépassées d'un point de vue POO puisque ça n'existe plus en Java/C#/Python/etc.), du coup c'est pratique de te donner une manière de faire commune, que tu as le plus de chance de retrouver plus tard en pratique wink
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

371

Si on veut. Pour le moment, arriver déjà d'une manière donnée sera plutôt pas mal.

Donc question, puisqu'on y est. grin

Si une méthode renvoie un objet string, je fais comment pour le détruire, cet objet, une fois que je n'en ai plus besoin ? J'appelle explicitement son destructeur ?

372

tu ne fais rien du tout, l'objet temporaire sera détruit une fois atteint la fin du scope (l'accolade fermante du niveau où tu as déclaré la variable recevant la string)
lors de sa destruction, son constructeur sera appellé et l'epace sur la pile libéré

dans le cas d'une référence, tu n'as rien à faire, et si c'est un pointeur généralement la classe est documentée pour dire si tu est responsable de la destruction du pointeur ou si c'est la classe qui s'en charge
avatar

373

En fait, je crée une classe dont une méthode renvoie une string (std).
Donc tu veux dire qu'à la fin de la fonction dans laquelle est renvoyée cette string, elle est détruite ? Ok. Ca serait gênant si c'était dans main que cette string était retournée (ie libération à la fin du programme) ?
Je me rends pas compte de la taille de la pile sur un PC... (je me dis juste que ça doit dépasser les 16 ko syndicaux d'une TI)

374

Si c'est juste une string seule, elle ne devrait pas poser de grave problème, mais si tu veux réduire la durée de vie d'une variable, tu peux utiliser un bloc:
void main(int argc, char *argv[]){
  {
    String chaine = fonction_retournant_un_string();
    // chaine est utilisable ici
  }
  //chaine a été détruite
}
avatar

375

Note que c'est ça qu'on appelle le passage par copie. Je me permets une petite indication sur les performances que tu n'es pas obligé de lire si tu as peur de mélanger:
string f(string g) {
    // a) copie de l'objet g (copy-constructor) dans un objet temporaire à retourner
    return g;
    // b) destruction de g
}

int main() {
    // 1) création implicite d'un objet via string("yop")
    // 2) création d'une copie de l'objet comme paramètre
    string h = f("yop");
    // 3) destruction de l'objet temporaire string("yop")
    // 4) recopie de l'objet temporaire retourné dans h (operator = )
    return 0;
    // 5) destruction de h
}

Ca te donne une idée de la complexité du truc. Comme la chaîne est dynamique, le constructeur invoque new/malloc, le destructeur invoque delete/free et l'opérateur = invoque les 2.
[Edit] Mais ce n'est PAS une raison pour ne pas utiliser ça! Il faut juste s'en rendre compte si un jour tu bosses sur des systèmes embarqués et que tu veux faire de l'opti critique wink
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

376

Oui, j'ai une petite idée du bordel en effet, sans compter que je passe mon temps à me demander quelle gueule ça peut avoir en assembleur grin

Et merci Uther top

377

Bon, m'aurais-t-on menti ? On m'avait dit que le C++ était simple, et qu'il suffisait de faire des additions avec n'importe quoi pour que ça marche embarrassed

J'ai donc écrit ça :
std::string s = Date:: Day + " " + Date::Month + " " + Date::Year;
Sachant que Day/Month/Year sont de int, pourquoi il me jette ce con ? Il a rien compris ou quoi ? embarrassed

ps tiens c'est phun, il veut bien d'un s = " " Date::Month;, mais il veut pas d'autre addition à la suite. qui a dit que c'était bien cpp ? embarrassed

378

379

C'est que comme C++ hérite de C les chaines littérales sont des char* et pas des string.

L'opérateur "+" des objets peut en effet être surchargé mais pas celui des types primitifs. On peut additionner les char* et les int avec les string. Mais on ne peut toujours pas additionner les char et int entre eux.

ate::Month + " " + Date::YearÇa devrait fonctionner avec :std::string s = std::string() + Date:: Day + " " + D

avatar

380

Nein, toujours pas, alors que pourtant ton explication m'a convaincu grin
std::string Date::GetDateString()
{
    std::string s = std::string() + Date:: Day + " " + Date::Month + " " + Date::Year;
    return s;
}

Même en spécifiant std::string(" "), ça veut pas...

381

Arg je me suis avancé en supposant que la classe std::string surchargeait l'opérateur + pour les int comme le fait la classe QString de Qt, mais visiblement, ce n'est pas le cas.

Pour le coup c'est bien dommage.
Si tu tiens a faire des addition entre string et int, tu pourrais te faire ta classe qui hérite de std::string et surcharge l'opérateur + pour les int
avatar

382

Jsavais pas qu'il y avait une classe Date en cpp. Ca m'étonne que tu puisses comme ça accéder à ses membres de façon statique de toute façon ( :: ).
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

383

Vu qu'elle n'est pas préfixée par "std::" contrairement aux string, je suppose que c'est Folco qui l'a faite.
avatar

384

Oui, ma première classe grin

J'ai fini toute la partie C++ du bouquin, lu une partie de la stl (me fait déjà chier avant d'avoir comencé), donc je retrousse le smanches et je m'y met ^^

385

Y a-t-il un moyen de convertir un int en string alors ? Ok, je peux l'écrire moi-même, mais si ça existe déjà... smile

386

387

histoire que ça resserve : tu as deux méthodes, soit les "atoi" & co hérités du C, soit une méthode plus lourde mais plus "C++ like" en utilisant stringstream :

#include <iostream>
#include <sstream>

int	main (void)
{
	std::stringstream	stream;
	int			i;

	stream << "27";
	stream >> i;

	std::cout << i << std::endl;
}
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

388

A ce moment si c'est toi qui as fait la classe Date c'est sûrement pas une très bonne idée de faire des membres statiques (mais je sais pas exactement ce que tu veux faire).
Une date c'est typiquement un truc que tu manipules comme des entiers par exemple, du coup ça devrait être des propriétés propre à l'instance wink
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

389

Je vois mal ce que tu veux dire, tu peux me le préciser stp ?

Mes dates ne sont pas déclarées en static (au sens C/C++), donc chaque instance possède sa propre date (enfin, c'est ce que je veux faire évidemment). oui

390

alors pourquoi tu y accèdes avec Date::getcekifo() au lieu de faire

Date *now = new Date();


puis

now->getcekifo();

?