Yeh purane Rule of Three ("agar destructor/copy-ctor/copy-assign mein se ek likhte ho, toh teeno likho") aur Rule of Five (do move ops bhi add karo) ka modern counterpart hai. Rule of Zero kehta hai: Rule of Three/Five ka sabse accha version woh hai jise aapko kabhi apply hi na karna pade.
Chaliye special members ki zaroorat ko scratch se derive karte hain.
Step 1 — Copying ka matlab kya hai?
Kisi value ko copy karne se ek independent object banana chahiye jo equal compare kare lekin mutable state share na kare. Ek plain int ke liye, bytes copy karna kaafi hai. Toh compiler ka default = memberwise copy sahi hai.
Yeh step kyun? Agar memberwise copy hamesha sahi hai, toh aapko kabhi hand-written copy ctor ki zaroorat nahi.
Step 2 — Memberwise copy kab toot-ta hai?
Yeh tab toot-ta hai jab koi member ek raw owning resource ho — new se aaya ek raw T*. Tab memberwise copy pointer ko duplicate karta hai, pointee ko nahi. Ab do objects ek hi buffer ki taraf point karte hain.
Yeh step kyun? Jis moment aap destructor mein delete[] p karte ho, default copy ek double-free bug ban jaata hai. Uss ek hand-written destructor ki wajah se aap Rule of Three mein aa jaate ho.
Step 3 — Cascade.
Destructor likhne ka matlab default copy galat hai → copy ctor + copy assign likhna padega → aur (post-C++11) jab aap destructor/copy declare karte ho toh compiler move operations generate karna band kar deta hai → performance ke liye moves bhi likhne padte hain → Rule of Five. Paanch tricky, exception-sensitive functions, sirf ek raw pointer ke liye.
struct Good { std::vector<int> p; // memory own karta hai, deeply copy karta hai, cheaply move karta hai Good(int n) : p(n) {} // na destructor, na copy, na move — sab sahi, sab free};
Yeh kyun kaam karta hai:std::vector ke paas pehle se ek sahi destructor (free karta hai), sahi copy (deep), aur sahi move (steal karta hai) hai. Memberwise generation simply vector ke sahi versions call karta hai. Correctness compose hoti hai, dobara likhi nahi jaati.
Socho ki har Lego brick pehle se jaanti hai ki khud ki perfect copy kaise banani hai aur khud ko kaise clean up karna hai. Agar aap sirf in smart bricks se ek spaceship banate ho, toh jab poori spaceship copy karni ho, aapko koi instructions nahi likhne — bas kehte ho "sab, khud ko copy karo," aur spaceship perfectly copy ho jaati hai. Copy instructions sirf tab likhne padte hain jab aapne ek dumb brick use ki ho (jaise ek sticky note jo ek shared box ki taraf point kare). Trick yeh hai: kabhi seedha dumb brick mat use karo. Dumb brick ko ek smart box mein ek baar wrap karo, aur smart box ko har jagah use karo.
Classes aise design karo ki members self-managing (RAII) types hon; phir zero special member functions likho aur compiler ko unhe generate karne do.
Ek destructor likhne se Rule of Five kyun force hota hai?
Hand destructor ka matlab manual resource ownership hai → default copy galat ho jaata hai (double free) → copy ops likhne padte hain → unhe declare karne se moves suppress ho jaate hain → moves bhi likhne padte hain.
Destructor declare karne ka (chahe =default bhi ho) move operations par kya side effect hota hai?
Yeh compiler-generated move constructor aur move assignment ko suppress karta hai, toh class silently copying pe fall back karti hai.
Ek class mein sirf ek std::unique_ptr member hai aur koi user-written specials nahi hain. Kya yeh copyable hai?
Nahi — copy implicitly deleted hai (unique_ptr copyable nahi hai); yeh move-only hai, jo automatically sahi hai.
Aapko special members kab likhne hi padte hain?
Sirf tab jab class directly ek non-RAII resource (raw new, FILE*, OS handle) own kare jiska koi self-managing wrapper na ho.
Jab kisi resource ka koi RAII wrapper na ho toh recommended fix kya hai?
Ek chhota sa RAII class likho jo uss resource ko wrap kare (apne specials ke saath), phir har doosri class Rule of Zero use kare.
Rule of Zero vs Rule of Three/Five — relationship kya hai?
Three/Five kehte hain "agar ek resource-managing special likhte ho, saare likho"; Rule of Zero kehta hai sabse accha application yeh hai ki RAII members compose karke kisi ki zaroorat hi na pade.