विषय पर बढ़ें

अंतिम अद्यतन:2026-10-12

C++ स्मार्ट पॉइंटर फ़ंक्शन पैरामीटर की तरह

C++那些事: स्मार्ट पॉइंटर कब फ़ंक्शन पैरामीटर बनता है

आमतौर पर हम देखते हैं कि कुछ फ़ंक्शन स्मार्ट पॉइंटर को पैरामीटर की तरह उपयोग करते हैं, जबकि कुछ फ़ंक्शन raw पॉइंटर — आख़िर कौन-सा उपयोग करें? इसका उपयोग सिद्धांत क्या है?

यह सेक्शन abseil की tips की मदद से समझाता है।

नीचे दिखाए अनुसार, इस कोड में क्या समस्या है?

bool CanYouPetTheDog(const std::shared_ptr<Dog>& dog,
                     absl::Duration min_delay) {
  return dog->GetLastPetTime() + min_delay < absl::Now();
}

CanYouPetTheDog फ़ंक्शन अपने dog पैरामीटर की ownership को प्रभावित नहीं करता, लेकिन इसका सिग्नेचर इसे std::shared_ptr में स्टोर करने की माँग करता है। ऐसा करने से एक खास ownership मॉडल पर एक अनावश्यक dependency पैदा होती है, भले ही फ़ंक्शन को खुद को इसकी ज़रूरत न हो। यह dependency caller को दूसरे मॉडल जैसे std::unique_ptr या stack पर ऑब्जेक्ट बनाने से रोकती है।

पॉइंटर/रेफ़रेंस का उपयोग

जब ownership प्रभावित नहीं होती तब रेफ़रेंस या पॉइंटर का उपयोग करें। रेफ़रेंस/पॉइंटर का उपयोग करके हम किसी खास ownership मॉडल पर dependency ख़त्म कर सकते हैं और अपने फ़ंक्शन को Dog टाइप के किसी भी ऑब्जेक्ट के साथ काम करने दे सकते हैं।

bool CanYouPetTheDog(const Dog& dog, absl::Duration min_delay) {
  return dog.GetLastPetTime() + min_delay < absl::Now();
}

उपरोक्त परिभाषा के साथ, caller का ownership मॉडल चाहे जो भी हो, फ़ंक्शन कॉल किया जा सकता है:

Dog stack_dog;
if (CanYouPetTheDog(stack_dog, delay)) { ... }

auto heap_dog = std::make_unique<Dog>();
if (CanYouPetTheDog(*heap_dog, delay)) { ... }

CustomPetPtr<Dog> custom_dog = CreateDog();
if (CanYouPetTheDog(*custom_dog, delay)) { ... }

अगर फ़ंक्शन पास की गई वैल्यू को बदलता है, तो mutable रेफ़रेंस या raw पॉइंटर पास करें, उपयोग वैसा ही रहता है जैसा ऊपर बताया गया।

स्मार्ट पॉइंटर का उपयोग

जब फ़ंक्शन ownership बदलता है तब स्मार्ट पॉइंटर का उपयोग करें, निम्नलिखित कोड अलग-अलग स्मार्ट पॉइंटर पैरामीटर्स के लिए कुछ overload देता है। पहला overload मानता है कि पास किए गए ऑब्जेक्ट की ownership संभाली जाएगी, दूसरा overload पास किए गए ऑब्जेक्ट में एक साझा रेफ़रेंस जोड़ता है। ये दोनों ऑपरेशन इस बात पर निर्भर करते हैं कि caller Dog की ownership के साथ कैसे पेश आता है। stack पर स्थित Dog की ownership नहीं ली जा सकती, क्योंकि stack से ownership छीनी नहीं जा सकती।

class Human {
 public:
  ...
  void Adopt(std::unique_ptr<Dog> dog) {
    pets_.push_back(std::move(dog));
  }
  void Adopt(std::shared_ptr<Cat> cat) {
    pets_.push_back(std::move(cat));
  }

 private:
  std::vector<std::shared_ptr<Pet>> pets_;
  ...
};

सारांश

अगर ownership transfer या modify नहीं होती, तो स्मार्ट पॉइंटर को फ़ंक्शन पैरामीटर की तरह उपयोग करने से बचना चाहिए।

https://abseil.io/tips/188

संबंधित विषय

टिप्पणियाँ