C++スマートポインタ:unique_ptr詳細
44325 ワード
文書ディレクトリ unique_ptr記述 声明 作用 関数ポインタ記述 まとめ unique_ptr記述
宣言
ヘッダファイル:デフォルトタイプ 配列タイプ さぎょう
shared_とptrの最大の違いはunique_ですptrは同じアドレスを共有することができず,アドレスを独占している.unique_ptrオブジェクトのライフサイクルが終了すると、参照されるアドレス空間も解放されます.
unique_ptrオブジェクトは主に2つの部分を含むメモリポインタ:主にオブジェクトのアドレス空間を管理するために使用されます.コンストラクション関数に割り当てられたアドレスであり、割り当て演算子およびresetメンバー関数によってアドレス空間の再指向を行うことができる.getとreleaseメンバー変数を単独でアクセスしてunique_を取得できます.ptrオブジェクトのアドレス空間. ストレージ削除器:削除器は呼び出すことができるオブジェクトです.主にunique_を削除するために使用されます.ptrオブジェクトのアドレス空間.現在のオブジェクトの変更は、付与演算子を使用してget_で行うことができます.deleterメンバー関数は単独でアクセスします.
関数ポインタの説明コンストラクタ である.構造関数;オブジェクトが空のunique_の場合ptr、すなわちget()=nullptrを使用すると、構造関数が機能しなくなります.そうしないと、 です. を出力します. が出力する. .
まとめ shared_ptrアドレス空間は複数のスマートポインタで共有することができず、実際の現在のオブジェクトアドレスの役割ドメインが終了すると、変更対象が占有するアドレス空間は から解放される. releaseメンバー関数を使用してunique_を転送ptr隊形のすべての輪、間もなくunique_ptrオブジェクトをunique以外に変換ptrオブジェクトは、アドレス を破壊しない を破壊するは、付与メタ演算子を用いる、reset関数と同様にアドレス空間を再指定し、同様にアドレス空間 を破壊する. unique_ptrオブジェクトの戻りインテリジェント使用メンバー関数
宣言
ヘッダファイル:
テンプレートクラス:template > class unique_ptr
template class unique_ptr;
shared_とptrの最大の違いはunique_ですptrは同じアドレスを共有することができず,アドレスを独占している.unique_ptrオブジェクトのライフサイクルが終了すると、参照されるアドレス空間も解放されます.
unique_ptrオブジェクトは主に2つの部分を含む
関数ポインタの説明
//unique_ptr constructor example
#include
#include
int main () {
std::default_delete<int> d;
//
std::unique_ptr<int> u1;
// null ,
std::unique_ptr<int> u2 (nullptr);
//
std::unique_ptr<int> u3 (new int);
// , ,
std::unique_ptr<int> u4 (new int, d);
// , , unique_ptr
std::unique_ptr<int> u5 (new int, std::default_delete<int>());
std::unique_ptr<int> u6 (std::move(u5));
std::unique_ptr<int> u7 (std::move(u6));
std::unique_ptr<int> u8 (std::auto_ptr<int>(new int));
std::cout << "u1: " << (u1?"not null":"null") << '
';
std::cout << "u2: " << (u2?"not null":"null") << '
';
std::cout << "u3: " << (u3?"not null":"null") << '
';
std::cout << "u4: " << (u4?"not null":"null") << '
';
std::cout << "u5: " << (u5?"not null":"null") << '
';
std::cout << "u6: " << (u6?"not null":"null") << '
';
std::cout << "u7: " << (u7?"not null":"null") << '
';
std::cout << "u8: " << (u8?"not null":"null") << '
';
return 0;
}
の出力は、u1: null
u2: null
u3: not null
u4: not null
u5: null
u6: null
u7: not null
u8: not null
get_deleter()
関数のように// unique_ptr destructor example
#include
#include
int main () {
auto deleter = [](int*p){
delete p;
std::cout << "[deleter called]
";
};
std::unique_ptr<int,decltype(deleter)> foo (new int,deleter);
std::cout << "foo " << (foo?"is not":"is") << " empty
";
return 0; // [deleter called]
}
が出力します.foo is not empty
[deleter called]
operator=
// unique_ptr::operator= example
#include
#include
int main () {
std::unique_ptr<int> foo;
std::unique_ptr<int> bar;
foo = std::unique_ptr<int>(new int (101)); // rvalue
//std::move foo bar, foo empty
// std::move unique_ptr
bar = std::move(foo); // using std::move
std::cout << "foo: ";
if (foo) std::cout << *foo << '
'; else std::cout << "empty
";
std::cout << "bar: ";
if (bar) std::cout << *bar << '
'; else std::cout << "empty
";
return 0;
}
出力:foo: empty
bar: 101
std :: unique_ptr :: get
メンバー、変更メンバー関数は管理されたunique_ptr
オブジェクトを返します.この関数の呼び出しはunique_を使用しません.ptrリリースポインタの所有権(すなわち、管理データをある時点で削除する責任を負います).このため、この関数が返す値は、新しい管理ポインタを構築するために使用できません.ポインタをアクティブに格納し、正常にリリースできるようにするには、release()
メンバー関数// unique_ptr::get vs unique_ptr::release
#include
#include
int main () {
// foo bar p
// --- --- ---
std::unique_ptr<int> foo; // null
std::unique_ptr<int> bar; // null null
int* p = nullptr; // null null null
foo = std::unique_ptr<int>(new int(10)); // (10) null null
// std::move foo bar
std::cout << "foo: " << foo.get() << std::endl;
bar = std::move(foo); // null (10) null
std::cout << "foo: " << foo.get() << std::endl;
std::cout << "bar: " << bar.get() << std::endl;
p = bar.get(); // null (10) (10)
*p = 20; // null (20) (20)
p = nullptr; // null (20) null
foo = std::unique_ptr<int>(new int(30)); // (30) (20) null
p = foo.release(); // null (20) (30)
*p = 40; // null (20) (40)
std::cout << "foo: ";
if (foo) std::cout << *foo << '
'; else std::cout << "(null)
";
std::cout << "bar: ";
if (bar) std::cout << *bar << '
'; else std::cout << "(null)
";
std::cout << "p: ";
if (p) std::cout << *p << '
'; else std::cout << "(null)
";
std::cout << '
';
delete p; // the program is now responsible of deleting the object pointed to by p
// bar deletes its managed object automatically
return 0;
}
を使用して、optionscompilationexecution
foo: 0x817a10
foo: 0
bar: 0x817a10
foo: (null)
bar: 20
p: 40
std :: unique_ptr :: release
現在のunique_は、メンバー関数の戻り値および空のポインタを変更することによって解放される.ptrポインタの所有権現在の呼び出しは管理オブジェクトを破壊することはなく、メンバー関数を変更してもオブジェクトは削除されず、他のエンティティがいつかオブジェクトを削除する必要があります.オブジェクトを強制的に削除するには、resetまたは付与演算子(std::move)// unique_ptr::release example
#include
#include
int main () {
std::unique_ptr<int> auto_pointer (new int);
int * manual_pointer;
*auto_pointer=10;
std::cout << " auto_pointer " << auto_pointer.get() << std::endl;
manual_pointer = auto_pointer.release();
std::cout << " auto_pointer " << auto_pointer.get() << std::endl;
std::cout << " manual_pointer " << manual_pointer<< std::endl;
// (auto_pointer is now empty)
std::cout << "manual_pointer points to " << *manual_pointer << '
';
delete manual_pointer;
return 0;
}
を使用して、次のように出力する必要があります.auto_pointer 0x3afffa0
auto_pointer 0
manual_pointer 0x3afffa0
manual_pointer points to 10
std::unique_ptr::reset
void reset (pointer p = pointer()) noexcept;
現在のunique_ptr
オブジェクトを破壊し、その所有権pを取得する.pが空である場合、現在のunique_ptr
オブジェクトも空である.現在のオブジェクトを解放し、オブジェクトが指すアドレス空間および内容を破壊しない場合、release
メンバー関数// unique_ptr::reset example
#include
#include
int main () {
std::unique_ptr<int> up; // empty
//reset up , up ,
up.reset (new int); // takes ownership of pointer
// null
std::cout << *up << " " << up.get() << '
';
*up=5;
std::cout << *up << " " << up.get() << '
';
up.reset (new int); // deletes managed object, acquires new pointer
*up=10;
std::cout << *up << " " << up.get() << '
';
up.reset(); // deletes managed object
return 0;
}
を使用して、0 0xd7dc70
5 0xd7dc70
10 0xd7dc90
std::unique_ptr::swap
は対象空間及び内容を交換し、アドレス空間// unique_ptr::swap example
#include
#include
int main () {
std::unique_ptr<int> foo (new int(10));
std::unique_ptr<int> bar (new int(20));
std::cout << "foo: " << *foo << " " << foo.get() << '
';
std::cout << "bar: " << *bar << " " << bar.get() << '
';
foo.swap(bar);
std::cout << "foo: " << *foo << " " << foo.get() << '
';
std::cout << "bar: " << *bar << " " << bar.get() << '
';
return 0;
}
を破壊することなく出力する:foo: 10 0x2cd9ae0
bar: 20 0x2cd9b00
foo: 20 0x2cd9b00
bar: 10 0x2cd9ae0
まとめ
reset
を使用すると、オブジェクトアドレス空間がリセットされ、再割り当てされます.アドレス空間get