Bonjour.
Il y a une chose qui me perturbe fortement au sujet des fonctions qui retournent un objet.
Le mieux c'est de prendre un exemple.
Voici une classe :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75 %:include <iostream> class ExampleString { public: ExampleString(); ExampleString(const char* paramZeroString); ExampleString(const ExampleString ¶mExampleString); void display(); ~ExampleString(); private: char* attrBuffer; }; ExampleString::ExampleString() {attrBuffer = nullptr;} ExampleString::ExampleString(const char* paramZeroString) { unsigned int localSize = 0; if (paramZeroString != nullptr) { while (paramZeroString[localSize] != 0) localSize++; if (localSize > 0) { attrBuffer = new char[localSize + 1]; for (unsigned int index = 0 ; index < localSize ; index++) attrBuffer[index] = paramZeroString[index]; attrBuffer[localSize] = 0; } else attrBuffer = nullptr; } else attrBuffer = nullptr; } ExampleString::ExampleString(const ExampleString ¶mExampleString) { ExampleString(paramExampleString.attrBuffer); } void ExampleString::display() { if (attrBuffer != nullptr) std::cout << '[' << reinterpret_cast<void*>(attrBuffer) << "] = " << attrBuffer << std::endl; else std::cout << "[nullptr]" << std::endl; } ExampleString::~ExampleString() { if (attrBuffer != nullptr) { delete[] attrBuffer; attrBuffer = nullptr; } }
Bon, je viens de saisir le code à la volée sans le vérifier, j'ai peut-être oublié des choses mais l'important est en gros de considérer que : Nous avons une classe "ExampleString" qui gère un pointeur de données en interne, dont la mémoire est allouée dans le constructeur puis libérée dans le destructeur.
Maintenant observons le code suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 %:include "class/ExampleString" ExampleString getBack() { ExampleString localExampleString = (char*)"BACK"; return localExampleString; } int main() { ExampleString mainExampleString = getBack(); mainExampleString.display(); return 0; }
Ce code implémente une fonction qui est sensée retourner un objet de type "ExampleString".
Et là rassurez-moi, dites-moi que le langage C++ est bien fait, qu'il ne fait pas appel au constructeur de copie suivi du destructeur de l'objet, mais qu'il étend seulement la portée de la variable retournée à la fonction appelante...
Bon j'avoue feindre l'ignorance, après vérification (sur gcc) il semblerait que malheureusement, lorsque ma fonction retourne l'objet "ExampleString" elle provoque un renouvellement dont j'aurais bien voulu me passer. Alors ma question est la suivante :
Comment puis-je faire en sorte d'éviter ce genre d'écriture de mémoire ridiculement lourd et inutile ?
Sachant que les deux solutions suivantes ont déjà été envisagées et semblent finalement hautement indésirables :
1. Retourner un pointer au lieu d'un objet, mais cela demande de le détruire après chaque appel de la fonction, enfin ça donne une catastrophe conceptuelle quoi ;
2. Créer des constructeurs et destructeurs intelligents à coup de mutables qui permettent à plusieurs instances de partager le même pointeur tant que les données n'ont pas besoin d'être modifiées. Ça résoud le problème mais ça alourdit énormément les méthodes de modification.
Une idée ?
Edit : Correction des erreurs dans le code présenté.
Partager