1260

Il peut pas, le type de retour de l'opérateur "->" est imposé. Et même s'il ne l'était pas, un programmeur C++ ne s'amuserait pas à coder ce genre de comportement, tout le monde sait bien que c'est stupide et il n'y a pas besoin d'utiliser un langage blindé de garde-fous pour apprendre à coder proprement.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

1261

squalyl (./1257) :
Comment accéder de manière propre a l'instance autrement que par un pointeur? chaque fois que tu déclares un objet faut recopier toutes les données de l'instance unique dans ton truc déclaré?

Ben si tu ne veux pas de recopie tu utilises un pointeur... Si tu retournes l'objet par valeur alors il y a recopie, ça vient de la définition même.
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

1262

Folco (./1254) :
J'ai aps réussi à utiliser l'opérateur [] du conteneur map... ( http://www.cplusplus.com/reference/stl/map/operator%5B%5D/ )

J'ai utilisé find() à la place, avec succès :
void Message::sendMessage(int ID)
{
    m_EntriesList->find(ID)->second->receive();
}


Mais à la base, je voulais écrire quelque chose du genre :
void Message::sendMessage(int ID)
{
    *m_EntriesList[ID]->receive();
}

avec:
    std::map<int, Receive*> *m_EntriesList;
et:
    m_EntriesList = new std::map<int, Receive*>;

Mais cette "solution" ne compilait pas,je ne sais pas trop pourquoi...
Sinon, j'arrive à faire les autres manipulations d'insertion et d'effacement dans le conteneur. smile

pourquoi est ce que tu utilises un pointeur vers une map ?
ça ne sert à rien et c'est source d'erreurs
tu devrais plutôt mettre directement la map dans ta classe
la bonne syntaxe :
// avec pointeur :
(*m_EntriesList)[ID]->receive();
// avec directement la classe
m_EntriesList[ID]->receive();

et puis je ne sais pas si c'est un oubli ou si c'est géré ailleurs, mais attention à toujours vérifier que tu ne vas pas accéder à un indice qui n'existe pas. si elle n'existait pas, [] va créer l'entrée et find() va te renvoyer m_EntriesList.end() qui n'est pas déréferençable.
avatar

1263

Folco (./1254) :
J'ai aps réussi à utiliser l'opérateur [] du conteneur map... ( http://www.cplusplus.com/reference/stl/map/operator%5B%5D/ )

J'ai utilisé find() à la place, avec succès :
void Message::sendMessage(int ID)
{
    m_EntriesList->find(ID)->second->receive();
}


Mais à la base, je voulais écrire quelque chose du genre :
void Message::sendMessage(int ID)
{
    *m_EntriesList[ID]->receive();
}

avec:
    std::map<int, Receive*> *m_EntriesList;
et:
    m_EntriesList = new std::map<int, Receive*>;

Mais cette "solution" ne compilait pas,je ne sais pas trop pourquoi...
Sinon, j'arrive à faire les autres manipulations d'insertion et d'effacement dans le conteneur. smile

À la place de:
*m_EntriesList[ID]->receive();
Essaye de faire:
(*m_EntriesList)[ID]->receive();
Si ça ne résoud pas ton problème de compilation, je ne sais pas où il peut être.

Et (probablement) rien à voir:
est-ce que:
m_EntriesList = new std::map<int, Receive*>;
compile?

Quoi qu'il en soit, je pense que:
m_EntriesList = new std::map<int, Receive*>();
est mieux.

1264

aze (./1262) :
pourquoi est ce que tu utilises un pointeur vers une map ? ça ne sert à rien et c'est source d'erreurs

Farpaitement d'accord, mais si je déclare un map dans les membres de ma classe, g++ va gueuler si je ne l'initialise pas dans la liste du constructeur, et je fait tout pour ne pas avoir de warnings. Et je sais plus pourquoi, j'avais pas trouvé la syntaxe pour initialiser un vector dans la liste d'init, et j'ai même pas essayé avec map.

Donc à revoir, arce que je suis bien d'accord avec toi sur le principe.
aze (./1262) :
et puis je ne sais pas si c'est un oubli ou si c'est géré ailleurs, mais attention à toujours vérifier que tu ne vas pas accéder à un indice qui n'existe pas. si elle n'existait pas, [] va créer l'entrée et find() va te renvoyer m_EntriesList.end() qui n'est pas déréferençable.

Il n'y a pas de raison qu'on s'adresse à un objet inexistant. Je pourrais faire cette vérification à des fins de débogage par contre, c'est sûr.
Jyaif (./1263) :
Essaye de faire: (*m_EntriesList)[ID]->receive();

J'ai essayé de jouer sur les parenthèses, j'ai peut-être pas essayé ça, je vais voir.
Jyaif (./1263) :
est-ce que:
m_EntriesList = new std::map; compile?

Oui.
Jyaif (./1263) :
Quoi qu'il en soit, je pense que: m_EntriesList = new std::map();

Je vois pas la différence fondamentale en fait, c'est le même constructeur qui va être appelé, pourquoi le spécifier ?

1265

Message::Message() : m_EntriesList(std::map<int, Receive*>)
=> Expected primary-expression before ')' token.

Et je l'emmerde, je sais pas comment faire. Et si je n'initialise pas m_EntriesList, il me fout un warning. neutral

EDIT !!!
Trouvé grin
Message::Message() : m_EntriesList(std::map<int, Receive*>())
La putain de paire de parenthèses dont Jyaif me parlait grin
Quel est le bon comportement à adopter pour ces parenthèses, sur quoi ça joue, je vois pas tous les tenants et aboutissants...

re-edit -> et du coup, le "m_EntriesList[ID]->receive();" marche, donc la solution de Jyaif devait marcher également.

Merci beaucoup pour tout, vous me faites bien avancer happy

1266

je ne comprends pas pourquoi g++ gueule si tu ne l'initialise pas explicitement.
si une variable membre n'est pas initialisée dans la liste du constructeur, c'est son constructeur par défaut qui est appelé.
ap<int, Receive*>())d'ailleurs la ligne Message::Message() : m_EntriesList(std::m n'a pas vraiment de sens : tu initialises par copie ton membre à partir d'une variable anonyme crée avec le constructeur par défaut.
e*>())virer m_EntriesList(std::map<int, Receiv devrait revenir au même, donc laisser le compilo appeler tout seul le constructeur par défaut
tu n'as pas besoin d'initialiser explicitement tous tes objets dans la liste de ton constructeur, seulement ceux dont le constructeur a besoin de paramètres ou les types de base
Folco (./1264) :
Jyaif (./1263) :
Quoi qu'il en soit, je pense que: m_EntriesList = new std::map();

Je vois pas la différence fondamentale en fait, c'est le même constructeur qui va être appelé, pourquoi le spécifier ?

à ma connaissance, les deux sont équivalents. une écriture ressemble à la construction d'objets simples : float a; string str; etc... et l'autre à la construction d'objets dont le constructeur prend des arguments.
avatar

1267

aze (./1266) :
je ne comprends pas pourquoi g++ gueule si tu ne l'initialise pas explicitement.[...]

Ah mais parfaitement d'accord également, je ne comprends pas pourquoi le constructeur sans argument n'est pas appelé par défaut, alors qu'ici je me tape une copie comme tu dis confus

Un spécialiste de g++ dans les parages ?

1268

Bon, je man ici : http://linux.die.net/man/1/g++

J'ai trouvé ça déjà :
The following -W... options are not affected by -Wall.
-Weffc++ (C ++ only)
    Warn about violations of the following style guidelines from Scott Meyers' Effective C ++ book: 
    *

    Item 11: Define a copy constructor and an assignment operator for classes with dynamically allocated memory.

    *

    Item 12: Prefer initialization to assignment in constructors. 

On parle ici de l'item 12 apparemment, et je parlais tout à l'heure du 11, à propos de la mise en private des opérateurs de copie et d'affectation.

en effet, j'avais activé ce switch (en fait, tous les switches ressemblant de près ou de loin à des warnings grin)

1269

squalyl (./1257) :
quel bordel pour un simple singleton! Comment accéder de manière propre a l'instance autrement que par un pointeur? chaque fois que tu déclares un objet faut recopier toutes les données de l'instance unique dans ton truc déclaré?

Justement, on interdit de copier l'objet en rendant le constructeur, le constructeur de copie et l'operator= privés et on ne permet donc que d'y accéder par pointeur ou référence.


Folco, pour ton problème avec g++, c'est quoi le warning exact que tu as?
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é

1270

Le warning est : "‘Message::m_EntriesList’ should be initialized in the member initialization list"
Comme dit mon edit du post précédent, g++ se la ferme sans ce switch, et c'est aussi bien ^^

1271

Oui bon, je pense que tu as compris maintenant pourquoi ce switch n'est pas activé par défaut. Les règles de Effective C++ sont loin d'être universellement appréciées!
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é

1272

ben même si elles ne sont pas universellement appréciées, je ne vois pas en quoi ne pas mettre le constructeur par défaut dans la liste d'init en constitue une violation
avatar

1273

Parce que le grand gourou auteur de ce livre a décrété qu'il faille qu'on le fasse explicitement. 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é

1274

ben justement non, on dirait plutôt que l'implémentation du warning en fait trop je ne vois pas de principe dans effective c++ qui t'oblige à faire ça
avatar

1275

http://www.cplusplus.com/reference/stl/map/operator%5B%5D/
Quelqu'un saurait si c'est une exception bad_alloc qui est levée si l'ajout d'un élément avec operator[] foire ?
Pas envie de me taper les sources de la classe couic

1276

Aucune idée. Et si ce n'est pas dans les specs, c'est pas une super idée de se baser dessus !

1277

C'est donc couillon ça ! On sait que ça peut foirer, mais on sait pas comment tritop
Tant pis, je vais revoir mon bouquin, je crois qu'on peut faire un catch (default) ou assimilé, ça ira bien pour cette fois embarrassed

1278

À priori si ça utilise le default allocator ça devrait être le cas, non ?
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

1279

heu il y a un problème quelque part, car ce n'est pas normal qu'il y ait une exception bad_alloc qui soit levée. ça veut dire qu'il n'a pas pu allouer de la mémoire pour placer le nouvel élément dans la map. ce n'est en aucun cas un moyen de savoir si la clé est déjà présente. pour ça, tu dois utiliser find()
avatar

1280

D'après ça http://www.sgi.com/tech/stl/Map.html et ça http://www.sgi.com/tech/stl/Allocators.html c'est alloc qui est utilisé, donc oui, je devrais me taper une exception bad_alloc.
insert() n'est pas plus spécifié à ce niveau que operator[] sad
Pour info, c'est à catch (unexpected) que je pensais, mais c'est pas utilisable parce que c'est mal normalisé, et ça peut carrément faire un terminate->abort sans crier gare, suivant les implémentations.

aze -> oui, j'ai pas encore implanté la vérification avec find ^^

1281

Singleton: Tu peux hériter d'un template singleton si tu veux mettre un peu plus de fun!

1282

Tiens, si bad_alloc dérivait d'une erreur de base de la STL, je pourrais l'intercepter, je serais sûr de mes billes, non ?

JS -> Oui, j'ai vu ça dans WP fr, ça me dit trop rien, j'ai instancié un objet global et ça roule. Faut que j'avance, je découvrirai au fur et à mesure, et ça c'est pas bloquant. smile

1283

Folco (./1280) :
D'après ça http://www.sgi.com/tech/stl/Map.html et ça http://www.sgi.com/tech/stl/Allocators.html c'est alloc qui est utilisé, donc oui, je devrais me taper une exception bad_alloc.
insert() n'est pas plus spécifié à ce niveau que operator[] sad
Pour info, c'est à catch (unexpected) que je pensais, mais c'est pas utilisable parce que c'est mal normalisé, et ça peut carrément faire un terminate->abort sans crier gare, suivant les implémentations.

aze -> oui, j'ai pas encore implanté la vérification avec find ^^

non mais dans tous les cas, tu n'as pas à intercepter l'exception pour retomber sur tes pas. ce n'est pas normal que tu ais cette exception. il doit y avoir un problème autre part.
je n'ai jamais eu à me préoccuper de cette exception depuis que je fais du c++
avatar

1284

Il a pas spécifié qu'il avait cette exception non ?
Ce que j'ai compris moi, c'est qu'il demandait si c'était bien celle-là qui était balancée.
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

1285

Exact, j'imagine qu'il y a une réallocation qui peut échouer, c'est tout. Je n'ai pas encore testé mon code (et pour cause, mon programme ne s'est jamais lancé, j'ai trop de classes à finaliser avant un premier run triso)

1286

aaah, ok. je pensais que cette exception était balancée ^^
avatar

1287

Et c'est reparti les misères...

Donc avec le switch kivabien en moins, j'ai réécrit mes classes utilisant des vecteurs. Typiquement, au lieu de "std::vector<Module*> *m_ModuleList;", je veux utiliser maintenant "std::vector<Module> m_ModuleList;"
C'est à dire avoir non pas un pointeur vers une liste de pointeurs de Module, mais... une liste de Module, tout simplement.

MAIS !

Pour ceux qui ont tout suivi mes périgrinations laborieuses, Module n'est qu'un classe abstraite de laquelle je dérive StaticModule.
Hors quand je fais m_ModuleList.push_back(StaticModule(arg)), il me sort une erreur parce qu'il a besoin d'instancier un objet Module, mais il n'y arrive pas parce que la classe est abstraite (sans blague). Pourquoi je n'ai pas de polymorphisme dans ce cas, étant donné que StaticModule est un objet Module ?

Qui plus est, il a l'air de vouloir faire une copie temporaire de l'objet StaticModule, de sorte qu'il faut que je définisse une méthode de recopie pour ne pas avoir des libérations non souhaitées d'objet pointés... Ca fait chier, au moins, avec ne serait-ce que "std::vector <Module*> m_ModuleList;", j'évitais ça. C'est pourtant la démarche à avoir ?

1288

Essaye avec un std::vector<Module*> wink
(De mémoire, tu ne stockes qu'une valeur dans ton std::vector… Et qui dit valeur dit copie !)
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes

1289

Voilà, j'ai déjà réécrit avec ce que tu proposes, et tout de suite tout marche. Mais pourquoi tenait-il tellement à instancier un Module quand j'utilisais vector<Module>, et que je faisait un push_back de StaticModule ?

1290

La réponse est dans ma parenthèse.
De toutes façons, si tu prends le temps d'y réfléchir un peu, en fait tu veux un Module*, et non pas un Module.
Et en réalité, le polymorphisme ne « marche pas » avec les valeurs (genre Module), uniquement avec les différents types de références (donc pointeurs et références C++, genre Module* ou Module&).

Réfléchis à comment ça fonctionnerait à bas niveau:
Module fait 16 octets.
StaticModule fait 24 octets. (Oui, une instance d'une classe dérivée ne peux pas faire moins qu'une instance de la classe parent, c'est logique tongue)
Comment tu met un StaticModule dans un Module ? wink
Réponse: Tu peux pas ! smile
avatar
Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes