前回shared_ptrの使い方を適当に勉強したので、早速使ってみるぞーと思って使ってみたら"あれ?これどうすんだ?"ってことがあったのでそれらの確認をします。
constは?
shared_ptrを引数で渡すにはとりあえずそのまま渡しても動きます
#include "stdafx.h" #include <memory> #include <iostream> class Hoge { public: Hoge(){} ~Hoge(){ std::cout << "Hogeのデストラクタだよ" << std::endl; } int number_; }; void func(std::shared_ptr<Hoge> hoge) { if(hoge == nullptr) return; std::cout << hoge->number_ << " " << hoge.use_count() << std::endl; } int _tmain(int argc, _TCHAR* argv[]) { { std::shared_ptr<Hoge> hoge1(new Hoge); hoge1->number_ = 5; func(hoge1); } return 0; }
ただ、これだと値渡しされるので関数func内ではuse_count()は2になります。
use_count()を増やす意味があるならこのままで良いですが基本的にはconst参照渡しでよいでしょう。
#include "stdafx.h" #include <memory> #include <iostream> class Hoge { public: Hoge(){} ~Hoge(){ std::cout << "Hogeのデストラクタだよ" << std::endl; } int number_; }; void func(const std::shared_ptr<Hoge>& hoge) { if(hoge == nullptr) return; std::cout << hoge->number_ << " " << hoge.use_count() << std::endl; } int _tmain(int argc, _TCHAR* argv[]) { { std::shared_ptr<Hoge> hoge1(new Hoge); hoge1->number_ = 5; func(hoge1); } return 0; }
これだと関数内でのuse_count()は1です。
ただし、ここでのconstはアドレスが変わらないって言う意味で、アドレスが指す先が変わらないというわけではないです。
つまり、ポインタで言うところのvoid func(Hoge * const hoge)的なことです。
#include "stdafx.h" #include <memory> #include <iostream> class Hoge { public: Hoge(){} ~Hoge(){ std::cout << "Hogeのデストラクタだよ" << std::endl; } int number_; }; void func(const std::shared_ptr<Hoge>& hoge) { if(hoge == nullptr) return; hoge->number_ = 10; std::cout << hoge->number_ << " " << hoge.use_count() << std::endl; } int _tmain(int argc, _TCHAR* argv[]) { { std::shared_ptr<Hoge> hoge1(new Hoge); hoge1->number_ = 5; func(hoge1); std::cout << hoge1->number_ << std::endl; // 10が表示される } return 0; }
そんならポインタで言うところのvoid func(const Hoge* hoge)はどうすんの?ってことになります。
⇒ void func(const shared_ptr
#include "stdafx.h" #include <memory> #include <iostream> class Hoge { public: Hoge(){} ~Hoge(){ std::cout << "Hogeのデストラクタだよ" << std::endl; } int number_; }; void func(const std::shared_ptr<const Hoge>& hoge) { if(hoge == nullptr) return; //hoge->number_ = 10; // コンパイル時エラーになるよ std::cout << hoge->number_ << " " << hoge.use_count() << std::endl; } int _tmain(int argc, _TCHAR* argv[]) { { std::shared_ptr<Hoge> hoge1(new Hoge); hoge1->number_ = 5; func(hoge1); std::cout << hoge1->number_ << std::endl; } return 0; }
恥ずかしながらなんでuse_count()が2になるのかがあんまり良く分かってません。
shared_ptr
dynamic_castは?
dynamic_castはできるなら使いたくないですが、それはそれとして使い方を知っとくことはいいことだろうと。
shared_ptrの場合はdynamic_castの変わりにdynamic_pointer_castを用いるそうです。
#include "stdafx.h" #include <memory> #include <iostream> class Hoge { public: Hoge(){} virtual ~Hoge(){ std::cout << "Hogeのデストラクタだよ" << std::endl; } int number_; }; class DerivedHogeA : public Hoge { public: DerivedHogeA(){} virtual ~DerivedHogeA(){} }; class DerivedHogeB : public Hoge { public: DerivedHogeB(){} virtual ~DerivedHogeB(){} }; int _tmain(int argc, _TCHAR* argv[]) { { std::shared_ptr<Hoge> hoge1(new DerivedHogeA); if(std::dynamic_pointer_cast<DerivedHogeA>(hoge1) == nullptr) std::cout << "hoge1はDerivedHogeAじゃないよ" << std::endl; else std::cout << "hoge1はDerivedHogeAだよ" << std::endl; if(std::dynamic_pointer_cast<DerivedHogeB>(hoge1) == nullptr) std::cout << "hoge1はDerivedHogeBじゃないよ" << std::endl; else std::cout << "hoge1はDerivedHogeBだよ" << std::endl; } return 0; }