Un unique_ptr
ne serait pas travailler en raison d' getDevice()
, droite?
Non, pas nécessairement. Ce qui est important ici est de déterminer la politique de propriété pour votre Device
objet, c'est à dire qui va être le propriétaire de l'objet pointé par votre (smart) pointeur.
Est-ce que ça va être l'instance de l' Settings
objet seul? Sera l' Device
objet doivent être détruits automatiquement lorsque l' Settings
objet est détruit, ou doit-il survivre à cet objet?
Dans le premier cas, std::unique_ptr
est ce que vous avez besoin, car il rend l' Settings
le seul (unique) propriétaire de l'objet pointé, et le seul objet qui est responsable de sa destruction.
Dans cette hypothèse, getDevice()
doit retourner une simple observation de pointeur (observer les pointeurs sont des pointeurs qui ne gardent pas l'objet pointé de son vivant). La forme la plus simple d'observer pointeur est un pointeur brut:
#include <memory>
class Device {
};
class Settings {
std::unique_ptr<Device> device;
public:
Settings(std::unique_ptr<Device> d) {
device = std::move(d);
}
Device* getDevice() {
return device.get();
}
};
int main() {
std::unique_ptr<Device> device(new Device());
Settings settings(std::move(device));
// ...
Device *myDevice = settings.getDevice();
// do something with myDevice...
}
[NOTE 1: Vous demandez peut-être pourquoi je suis à l'aide de matières pointeurs ici, quand tout le monde n'arrête pas de raconter que les pointeurs sont mauvais, dangereux et dangereux. En fait, c'est un précieux avertissement, mais il est important de le mettre dans le bon contexte: les pointeurs sont mauvais quand il est utilisé pour effectuer manuel de gestion de la mémoire, c'est à dire l'allocation et la désallocation des objets par le biais new
et delete
. Lorsque utilisé uniquement comme un moyen de parvenir à la référence de la sémantique et de la passer autour de la non-propriété, de l'observation des pointeurs, il n'y a rien d'intrinsèquement dangereux en raw pointeurs, sauf peut-être pour le fait que l'on doit prendre soin de ne pas déréférencer un bancales pointeur. - LA FIN DE LA NOTE 1]
[NOTE 2: Comme il est apparu dans les commentaires, dans ce cas particulier où la propriété est unique et la propriété de l'objet est toujours la garantie d'être présent (c'est à dire les données internes membre device
ne sera jamais nullptr
), de la fonction getDevice()
pourrait (et devrait peut-être) de retour d'une référence plutôt qu'un pointeur. C'est vrai, j'ai décidé de retourner un pointeur brut ici parce que je voulais que cela soit une réponse courte, que l'on peut généraliser au cas où l' device
pourrait être nullptr
, et de montrer que les pointeurs sont OK tant qu'on ne les utilise pas de manuel de gestion de la mémoire. - LA FIN DE LA NOTE 2]
La situation est radicalement différente, bien sûr, si votre Settings
objet ne doit pas avoir la propriété exclusive de l'appareil. Cela pourrait être le cas, par exemple, si la destruction de l' Settings
objet ne devrait pas impliquer la destruction de l'souligné Device
objet.
C'est quelque chose que vous seul en tant que concepteur de votre programme peut dire; à partir de l'exemple que vous fournissez, il est difficile pour moi de dire si c'est le cas ou pas.
Pour vous aider à comprendre, vous pouvez vous demander s'il existe d'autres objets en dehors de Settings
qui ont le droit de conserver l' Device
objet vivant, tant qu'ils détiennent un pointeur vers elle, au lieu d'être des observateurs passifs. Si c'est effectivement le cas, alors vous avez besoin d'une propriété partagée de la politique, qui est ce que l' std::shared_ptr
offre:
#include <memory>
class Device {
};
class Settings {
std::shared_ptr<Device> device;
public:
Settings(std::shared_ptr<Device> const& d) {
device = d;
}
std::shared_ptr<Device> getDevice() {
return device;
}
};
int main() {
std::shared_ptr<Device> device = std::make_shared<Device>();
Settings settings(device);
// ...
std::shared_ptr<Device> myDevice = settings.getDevice();
// do something with myDevice...
}
Avis, weak_ptr
est une observation de pointeur, pas un propriétaire de pointeur - en d'autres termes, il ne tient pas de l'objet pointé est vivante que si tous les autres de posséder des pointeurs vers l'objet pointé hors de portée.
L'avantage de l' weak_ptr
plus régulière d'un pointeur brut, c'est que vous pouvez sans risque dire qu' weak_ptr
est bancale ou pas (c'est à dire qu'il pointe vers un objet valide, ou si l'objet à l'origine, a souligné a été détruit). Cela peut être fait par l'appel de la expired()
des membres de la fonction sur l' weak_ptr
objet.