Le premier, je reprends ton code et je le complète.
class Truc {
public:
void bar(MyClass* p) {
m_myclass = p;
}
void f() {
m_myclass->dosomething();
}
private:
MyClass* m_myclass;
};
class MyClass{
public:
void machin(Truc & t){
// appel de la fonction bar membre de Truc
t.bar(this);
}
};
int main() {
Truc t;
{
MyClass m;
m.machin(t);
}
t.f();
}
Jouer avec les pointeurs est donc problématique si on n'a pas assimilé les autres notions. Même sans multi-threads.
A la rigueur, si je demande en entretien d'embauche quel est le problème de ce code (sans donner le main), c'est beaucoup plus important que de connaître les pointeurs nus ou intelligents.
Le second point : std::optional possède l'ownership. Tu ne peux pas écrire :
void f(std::optional<Entity>);
Entity e;
f(e);
Sauf bien sur a utiliser par exemple optional<reference_wrapper<Object>>, mais cela n'apporte pas forcement beaucoup plus de garantie qu'un pointeur nu. Il y aura probablement encore des use cases pour les pointeurs nus.
Je ne vois pas le truc a propos d'optional et l'ownership.
Un Optional<T>, c'est (dessous le capot) une zone mémoire assez grande pour contenir un T + un booléen qui dit si cette zone est considérée comme contenant un objet T en état de marche , ou juste un espace réservé dont on ne fait rien pour l'instant.
template <typename T>
class Optionnel {
bool isPresent;
char data [sizeof(T)];
};
Le tout avec un peu de confiture syntaxique et des méthodes qui rendent la chose présentable.
value() qui retourne une référence à data considéré comme objet de type T
un constructeur avec paramètre qui lance l'initialisation de data, et met l'indicateur à vrai
le destructeur qui lance la destruction de data si isPresent est vrai,
etc.
Donc l'objet désigné par un optional, il est contenu dans l'optional comme une donnée membre l'est dans une structure. Du coup je ne vois pas le rapport avec la discussion sur les pointeurs.
Un optional n'est rien de plus qu'un unique_ptr en fait. Cela remplace un des use cases des pointeurs nus : le fait de pouvoir representer nullptr ou un objet. Avec optional, on supprime une partie des utilisations des pointeurs.
- demande sizeof( optional<UnGrosMachin>) pour voir
- essaie de faire un arbre binaire avec
class Node
public:
int data;
optional<Node> left; // NON NON
optional<Node> right;
};
EDIT : On aurait pu imaginer qu'un optional <T> ça soit la donnée d'un boolean (present/absent) et d'un pointeur de T, valide si le booléen est présent, alloué si l'optionnel contient quelque chose et libéré quand on le vide. Sauf que c'est pas ça. Ca contient l'espace de l'objet contenu.
<< This subclause describes class template optional that represents optional objects. An optional object for object types is an object that contains the storage for another object and manages the lifetime of this contained object, if any. >>
Il est bien précisé en note 1 de 5.4 : << Implementations are not permitted to use additional storage, such as dynamic memory, to allocate its contained value. >>
Oui, je pensais surtout au use cases d'utiliser optional pour remplacer certaines utilisation des raw ptr et unique_ptr. C'est dans ce sens là que koala01 parlait de optional. (Mais je ne savais pas pour ce détail imposé à l'implémentation, ce qui est une bonne chose, justement parce que cela le distingue de unique_ptr)
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Discord NaN. Mon site.
Discord NaN. Mon site.
Discord NaN. Mon site.