Smart Pointers
Ownership, RAII और Smart Pointers
Pointer location बताता है; ownership बताता है resource को alive और release कौन रखेगा। Smart pointer type में dynamic ownership express करता और RAII से scope/return/exception पर cleanup करता है।
| Need | Representation |
|---|---|
| Scoped object | Value |
| Dynamic sequence | vector/string |
| Exclusive owner | unique_ptr |
| Shared lifetime | shared_ptr |
| Shared object observer | weak_ptr |
| Ordinary non-owner | Reference/documented pointer |
unique_ptr: Exclusive Ownership
auto score=std::make_unique<int>(95);
std::cout<<*score;
score.reset();unique_ptr moveable लेकिन copyable नहीं। make_unique concise direct ownership देता है।
| Member | Use |
|---|---|
| get | Raw observation, ownership stays |
| * / -> | Non-null object access |
| reset | Current release, new own |
| release | Ownership छोड़कर raw pointer |
| swap | Owners exchange |
| bool | Non-null test |
Move और API Design
std::unique_ptr<Student> make_student(std::string n){
return std::make_unique<Student>(std::move(n));
}
void enroll(std::unique_ptr<Student> student){ }
auto learner=make_student("Aman");
enroll(std::move(learner));| Intent | Type |
|---|---|
| Use only | const T&/T& |
| Optional non-owner | Documented T* |
| Take ownership | unique_ptr by value |
| Reseat owner | unique_ptr& |
| Create owner | Return unique_ptr |
Function केवल object use करता है तो smart pointer parameter न लें। Move के बाद unique_ptr empty है; check/reassign के बिना dereference न करें।
shared_ptr और Control Block
auto course=std::make_shared<Course>("C++");
auto second_owner=course;
std::cout<<course.use_count(); // 2 hereControl block shared owners और weak observers track करता है। Last shared owner पर object destroy होता; weak observers रहने तक control block रह सकता है। Ordinary construction में make_shared prefer करें।
Widget* raw=new Widget;
std::shared_ptr<Widget> a(raw);
std::shared_ptr<Widget> b(raw); // गलत: two control blocksOne owner बनाकर उसी shared_ptr को copy करें।use_count diagnostic है, synchronization rule नहीं। Control block safety pointed object को thread-safe नहीं बनाती। this से नया shared_ptr न बनाएं; जरूरत में enable_shared_from_this लें।
weak_ptr, lock और Cycles
auto owner=std::make_shared<int>(42);
std::weak_ptr<int> observer=owner;
if(auto temporary=observer.lock()) std::cout<<*temporary;
owner.reset();
if(observer.expired()) std::cout<<"Object ended";weak_ptr object alive नहीं रखता। lock empty या temporary shared owner देता है। expired check के बाद अलग access की जगह lock करें।
struct Child;
struct Parent{std::shared_ptr<Child> child;};
struct Child{std::weak_ptr<Parent> parent;};दोनों directions shared हों तो cycle cleanup रोक सकती है; back-link weak रखें।
Custom Deleters और Arrays
using File=std::unique_ptr<std::FILE,decltype(&std::fclose)>;
File file(std::fopen("report.txt","w"),&std::fclose);
if(!file){ /* failure */ }
auto data=std::make_unique<int[]>(100);
data[0]=7;Deleter resource से match और non-throwing हो। Unique_ptr array specialization delete[]/indexing देता है, लेकिन ordinary sequence में size/iterators के कारण vector बेहतर है। PImpl में owner destructor उस जगह define करें जहां implementation type complete हो।
Complete Ownership Lab और Output
auto learner=std::make_unique<Student>("Aman");
std::cout<<"Owns before move: "<<bool(learner)<<'\n';
enroll(std::move(learner));
std::cout<<"Owns after move: "<<bool(learner)<<'\n';
auto score=std::make_shared<int>(42);
std::weak_ptr<int> observer=score;
if(auto locked=observer.lock()) std::cout<<*locked;
score.reset();enroll parameter ने exclusive ownership लिया और scope end पर Student destroy हुआ। weak observer strong count नहीं बढ़ाता और sole owner reset पर expired हो गया।
Mistakes, Practice और Review
| Mistake | Correction |
|---|---|
| shared_ptr default | Value/unique prefer |
| unique_ptr copy | Intentional move |
| One raw से two owners | One owner copy/move |
| Shared cycle | Weak back-link |
| Access के लिए shared param | Reference/view |
| get pointer delete | Owner cleans |
| release then lose | Immediate transfer |
| Pointee thread-safe assume | Separate synchronization |
Practice: Shape factory, shared Course, weak Parent–Child, FILE custom deleter और PImpl class बनाएं।
- Value possible?
- Exclusive/shared?
- Transfer visible?
- Borrow lifetime?
- Cycle?
- Deleter?
- Virtual destruction?
- Thread safety?
Authoritative संदर्भ
Ownership और API guidance current draft/Core Guidelines से verified है: default unique ownership और lifetime semantics में ही smart-pointer parameters।
