C++/C++14/SmartPointer
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
[[C++/C++14]]
Effective Modern C++
- C++11/14 プログラムを進化させる42項目
Scott Meyers
O'reilly Japan
ISBN978-4-87311-736-2
*[[C++/C++14/SmartPointer]] [#i29cd8c9]
C++11のスマートポインタ
- std::auto_ptr C++98から残されたもので非推奨。
- std::unique_ptr std::auto_ptr でできることはすべて可能...
- std::shared_ptr
- std::weak_ptr
*項目18: 独占するリソースの管理には std::unique_ptr を用...
unique_ptr のサイズは、デフォルトでは raw ポインタと同じ...
と想定して構わない。
std::unique_ptr は exclusive ownership (排他的所有権)セマ...
std::unique_ptr は指しているデータがnull以外の場合はそれ...
unique_ptr をmoveすると所有権もmove先に移る(その場合は元...
すなわち unique_ptr は move-only type でありコピーはでき...
unique_ptr を破棄すると対象のリソースも破棄する(デフォル...
class Investment { ... };
class Stock: public Investment { ... };
class Bond: public Investment { ... };
class RealEsatte: public Investment { ... };
template<typename... Ts>
std::unique_ptr<Investment> // return type
makeInvestment(Ts&&... params);
呼び出し側
{
...
auto pInvestment = makeInvestment( arguments ); // std...
...
} // destory *pInvestment
デフォルトでは delete いおり破棄されるが、custom deleter ...
auto delInvmt = [](Investment* pInvestment) {
makeLogEntry(pInvenstment);
delete pInvestment;
}
template<typename... Ts>
std::unique_ptr<Investment, decltype(delInvmt)> // retu...
makeInvestment(Ts&&... params) {
std::unique_ptr<Investment, decltype(delInvmt)> pInv(n...
if (/* a Stock object should be created */ ) {
pInv.reset(new Stock(std::forward<Ts>(params)...));
} else if (/* a Bond object should be created */ ) {
pInv.reset(new Bond(std::forward<Ts>(params)...));
} else if (/* a RealEstate object should be created */...
pInv.reset(new RealEstate(std::forward<Ts>(params).....
}
return pInv;
}
- makeInvestment が返したオブジェクトの custom deleter は...
- custom deleter を使用する場合は、その型を std::unique_p...
- raw ポインタを std::unique_ptr へ代入しようとしてもコン...
- new を実行するたびに std::forward におり makeInvestment...
- custom deleter の仮引数の型は Investment* である。makeI...
class Investment {
public:
...
virtual ~Investment();
...
}
C++14 には関数の戻り型を推論する機能があるため、makeInves...
tmplate<typename... Ts>
auto makeInvestment(Ts&&... params) {
auto delInvmt = [](Investment* pInvestment) {
makeLogEntry(pInvestment);
delete pInvestment;
};
std::unique_ptr<Investment, decltype(delInvmt)> pInv(n...
if ( ... ) {
pInv.reset(new Stock(std::forward<Ts>(params)...));
} else if ( ... ) {
pInv.reset(new Bond(std::forward<Ts>(params)...));
} else if ( ... ) {
pInv.reset(new RealEstate(std::forward<Ts>(params).....
}
return pInv;
}
デフォルトの deleter を使用する場合は std::unique_ptr の...
しかし、custom deleter を用いる場合は、1 or 2ワードサイズ...
また、関数オブジェクトを与えると、関数オブジェクトが保持...
関数オブジェクトが状態を持たなければサイズは変化しないの...
auto delInvmt1 = [](Investment* pInvestment) { // custom...
makeLogEntry(pInvestment); // as sta...
delete pInvestment; // labmda
};
template<typename... Ts> // re...
std::unique_ptr<Investment, decltype(delInvmt1)> // ha...
makeInvestment(Ts&&... args); // In...
void delInvmt2(Investment* pInvestment) { // custom...
makeLogEntry(pInvestment); // as fun...
delete pInvestment;
}
template<typename... Ts> // ...
std::unique_ptr<Investment, void (*)(Investment*)> // ...
makeInvestment(Ts&&... params); // function poi...
}
std::unique_ptr には2つの形式がある。
- 単一オブジェクト用 std::unique_ptr
- 配列 std::unique_ptr<T[]>
**重要ポイント [#uaae81a0]
- std::unique_ptr は、独占所有するリソース管理用の、サイ...
- デフォルトでは、リソースは delete により破棄されるが、c...
- std::unique_ptr の std::shared_ptr への変換は容易である。
*項目19: 共有するリソースの管理には std::shared_ptr を用...
std::shared_ptr を介して使用するオブジェクトのライフタイ...
そのオブジェクトを指す、最後の std::shared_ptr がオブジェ...
std::shared_ptr はリソースの reference count からそのリソ...
reference count により次の性質を持つ。
- shared::shared_ptr のサイズが raw ポインタの2倍になる。
- reference counter を動的にメモリ割り当てしなければなら...
- reference counter の increment/decrement はアトミックに...
std::unique_ptr と同様に std::shared_ptr でもリソースを破...
custom deleter も使用できるが、対応は std::unique_ptr と...
std::unique_ptr では deleter の型がスマートポインタの型の...
auto loggingDel = [](Widget *pw) { // custom deleter
makeLogEntry(pw);
delete pw;
};
std::unique_ptr<Widget, decltype(loggingDel)> // delete...
upw(new Widget, loggingDel); // part o...
std::shared_ptr<Widget> // deleter type is not
spw(new Widget, loggingDel); // part of ptr tpye
std::shared_ptr と std::unique_ptr の違いについて
- std::shared_ptr の設計の方が柔軟性に優れている。 ~
std::shared_ptr<widget> が2つあり、それぞれ異なる型の cus...
auto customDeleter1 = [](Widget *pw) { ... }; // custom...
auto customDeleter2 = [](Widget *pw) { ... }; // with a...
std::shared_ptr<Widget> pw1(new Widget, customDeleter1);
std::shared_ptr<Widget> pw1(new Widget, customDeleter2);
上の例の pw1 と pw2 の型は同じため、同じ型のコンテナに持...
std::vector<std::shared_ptr<Widget>> vpw[ pw1, pw2 };
また、pw1 と pw2 は相互に代入可能であり、いずれも std::sh...
- custom deleter をしていしても std::shared_ptr のサイズ...
std::shared_ptr オブジェクトのサイズは deleter に関係なく...
終了行:
[[C++/C++14]]
Effective Modern C++
- C++11/14 プログラムを進化させる42項目
Scott Meyers
O'reilly Japan
ISBN978-4-87311-736-2
*[[C++/C++14/SmartPointer]] [#i29cd8c9]
C++11のスマートポインタ
- std::auto_ptr C++98から残されたもので非推奨。
- std::unique_ptr std::auto_ptr でできることはすべて可能...
- std::shared_ptr
- std::weak_ptr
*項目18: 独占するリソースの管理には std::unique_ptr を用...
unique_ptr のサイズは、デフォルトでは raw ポインタと同じ...
と想定して構わない。
std::unique_ptr は exclusive ownership (排他的所有権)セマ...
std::unique_ptr は指しているデータがnull以外の場合はそれ...
unique_ptr をmoveすると所有権もmove先に移る(その場合は元...
すなわち unique_ptr は move-only type でありコピーはでき...
unique_ptr を破棄すると対象のリソースも破棄する(デフォル...
class Investment { ... };
class Stock: public Investment { ... };
class Bond: public Investment { ... };
class RealEsatte: public Investment { ... };
template<typename... Ts>
std::unique_ptr<Investment> // return type
makeInvestment(Ts&&... params);
呼び出し側
{
...
auto pInvestment = makeInvestment( arguments ); // std...
...
} // destory *pInvestment
デフォルトでは delete いおり破棄されるが、custom deleter ...
auto delInvmt = [](Investment* pInvestment) {
makeLogEntry(pInvenstment);
delete pInvestment;
}
template<typename... Ts>
std::unique_ptr<Investment, decltype(delInvmt)> // retu...
makeInvestment(Ts&&... params) {
std::unique_ptr<Investment, decltype(delInvmt)> pInv(n...
if (/* a Stock object should be created */ ) {
pInv.reset(new Stock(std::forward<Ts>(params)...));
} else if (/* a Bond object should be created */ ) {
pInv.reset(new Bond(std::forward<Ts>(params)...));
} else if (/* a RealEstate object should be created */...
pInv.reset(new RealEstate(std::forward<Ts>(params).....
}
return pInv;
}
- makeInvestment が返したオブジェクトの custom deleter は...
- custom deleter を使用する場合は、その型を std::unique_p...
- raw ポインタを std::unique_ptr へ代入しようとしてもコン...
- new を実行するたびに std::forward におり makeInvestment...
- custom deleter の仮引数の型は Investment* である。makeI...
class Investment {
public:
...
virtual ~Investment();
...
}
C++14 には関数の戻り型を推論する機能があるため、makeInves...
tmplate<typename... Ts>
auto makeInvestment(Ts&&... params) {
auto delInvmt = [](Investment* pInvestment) {
makeLogEntry(pInvestment);
delete pInvestment;
};
std::unique_ptr<Investment, decltype(delInvmt)> pInv(n...
if ( ... ) {
pInv.reset(new Stock(std::forward<Ts>(params)...));
} else if ( ... ) {
pInv.reset(new Bond(std::forward<Ts>(params)...));
} else if ( ... ) {
pInv.reset(new RealEstate(std::forward<Ts>(params).....
}
return pInv;
}
デフォルトの deleter を使用する場合は std::unique_ptr の...
しかし、custom deleter を用いる場合は、1 or 2ワードサイズ...
また、関数オブジェクトを与えると、関数オブジェクトが保持...
関数オブジェクトが状態を持たなければサイズは変化しないの...
auto delInvmt1 = [](Investment* pInvestment) { // custom...
makeLogEntry(pInvestment); // as sta...
delete pInvestment; // labmda
};
template<typename... Ts> // re...
std::unique_ptr<Investment, decltype(delInvmt1)> // ha...
makeInvestment(Ts&&... args); // In...
void delInvmt2(Investment* pInvestment) { // custom...
makeLogEntry(pInvestment); // as fun...
delete pInvestment;
}
template<typename... Ts> // ...
std::unique_ptr<Investment, void (*)(Investment*)> // ...
makeInvestment(Ts&&... params); // function poi...
}
std::unique_ptr には2つの形式がある。
- 単一オブジェクト用 std::unique_ptr
- 配列 std::unique_ptr<T[]>
**重要ポイント [#uaae81a0]
- std::unique_ptr は、独占所有するリソース管理用の、サイ...
- デフォルトでは、リソースは delete により破棄されるが、c...
- std::unique_ptr の std::shared_ptr への変換は容易である。
*項目19: 共有するリソースの管理には std::shared_ptr を用...
std::shared_ptr を介して使用するオブジェクトのライフタイ...
そのオブジェクトを指す、最後の std::shared_ptr がオブジェ...
std::shared_ptr はリソースの reference count からそのリソ...
reference count により次の性質を持つ。
- shared::shared_ptr のサイズが raw ポインタの2倍になる。
- reference counter を動的にメモリ割り当てしなければなら...
- reference counter の increment/decrement はアトミックに...
std::unique_ptr と同様に std::shared_ptr でもリソースを破...
custom deleter も使用できるが、対応は std::unique_ptr と...
std::unique_ptr では deleter の型がスマートポインタの型の...
auto loggingDel = [](Widget *pw) { // custom deleter
makeLogEntry(pw);
delete pw;
};
std::unique_ptr<Widget, decltype(loggingDel)> // delete...
upw(new Widget, loggingDel); // part o...
std::shared_ptr<Widget> // deleter type is not
spw(new Widget, loggingDel); // part of ptr tpye
std::shared_ptr と std::unique_ptr の違いについて
- std::shared_ptr の設計の方が柔軟性に優れている。 ~
std::shared_ptr<widget> が2つあり、それぞれ異なる型の cus...
auto customDeleter1 = [](Widget *pw) { ... }; // custom...
auto customDeleter2 = [](Widget *pw) { ... }; // with a...
std::shared_ptr<Widget> pw1(new Widget, customDeleter1);
std::shared_ptr<Widget> pw1(new Widget, customDeleter2);
上の例の pw1 と pw2 の型は同じため、同じ型のコンテナに持...
std::vector<std::shared_ptr<Widget>> vpw[ pw1, pw2 };
また、pw1 と pw2 は相互に代入可能であり、いずれも std::sh...
- custom deleter をしていしても std::shared_ptr のサイズ...
std::shared_ptr オブジェクトのサイズは deleter に関係なく...
ページ名: