স্মার্ট পয়েন্টারটি কী এবং আমি কখন এটি ব্যবহার করব?


1818

স্মার্ট পয়েন্টারটি কী এবং আমি কখন এটি ব্যবহার করব?



2
নোট করুন যে ভিজ্যুয়াল স্টুডিও 2005-এ স্ট্যান্ড :: অটো_পিটার বাস্তবায়ন মারাত্মকভাবে ভেঙে গেছে। <br> http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=98871 <br> http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101842 ব্যবহার করুন পরিবর্তে বেশী উত্সাহ দিন।
রিচার্ড

25
বিষয় সম্পর্কে দুটি দুর্দান্ত নিবন্ধ: - স্মার্ট পয়েন্টার - কী, কেন, কোনটি? - সপ্তাহের গুরু # 25
লেজার

1
বিভিন্ন স্বাদের স্মার্ট পয়েন্টার তৈরির নব্য কৌতুক সম্পর্কে আলেকজান্দ্রেস্কুর (ফ্রি) অধ্যায়টি এখানে রয়েছে: informit.com/articles/article.aspx?p=31529 তার প্রয়োগে, তিনি কোন বৈশিষ্ট্য চান তা নির্দিষ্ট করতে তিনি "নীতি" হিসাবে টেমপ্লেট যুক্তি ব্যবহার করেন ( উদাহরণস্বরূপ, রেফারেন্স গণনা), যেখানে স্ট্যান্ডার্ড লাইব্রেরি পৃথক ক্লাস ব্যবহার করে। নোট করুন যে তিনি std :: অনন্য_পিট্রির মতো কিছু তৈরি করার জন্য মূলসূত্রের রেফারেন্স উপলব্ধ হওয়ার আগেও লিখেছিলেন।
ধাতু

আমি উপরের প্রশ্নটিতে আরও একটি পয়েন্ট যুক্ত করতে চাই, স্মার্ট পয়েন্টার std :: শেয়ার_ptr এর সাবস্ক্রিপ্ট অপারেটর নেই এবং পন্টার গাণিতিক সমর্থন করে না, আমরা পয়েন্টার ইন বিল্ট পাওয়ার জন্য get () ব্যবহার করতে পারি।
Suresh এম

উত্তর:


1883

হালনাগাদ

এই উত্তরটি বরং পুরানো, এবং তাই সেই সময়ে 'ভাল' কী ছিল তা বর্ণনা করে যা বুস্ট গ্রন্থাগারের দ্বারা সরবরাহিত স্মার্ট পয়েন্টার ছিল। সি ++ 11 সাল থেকে, স্ট্যান্ডার্ড লাইব্রেরি পর্যাপ্ত স্মার্ট পয়েন্টার টাইপ সরবরাহ করেছে, এবং তাই আপনার ব্যবহারের পক্ষে উচিত std::unique_ptr, std::shared_ptrএবং std::weak_ptr

এছাড়াও ছিল std::auto_ptr। এটি অনেকটা একটি স্কোপড পয়েন্টারের মতো ছিল, কেবল এটির অনুলিপি করার মতো "বিশেষ" বিপজ্জনক ক্ষমতাও ছিল - যা অপ্রত্যাশিতভাবে মালিকানাও স্থানান্তর করে।
এটি সি ++ 11 এ অবহেলা করা হয়েছিল এবং সি ++ 17 এ সরানো হয়েছে , সুতরাং আপনার এটি ব্যবহার করা উচিত নয়।

std::auto_ptr<MyObject> p1 (new MyObject());
std::auto_ptr<MyObject> p2 = p1; // Copy and transfer ownership. 
                                 // p1 gets set to empty!
p2->DoSomething(); // Works.
p1->DoSomething(); // Oh oh. Hopefully raises some NULL pointer exception.

পুরানো উত্তর

স্মার্ট পয়েন্টার হ'ল এমন একটি শ্রেণি যা "কাঁচা" (বা 'বেয়ার') সি ++ পয়েন্টারকে আবৃত করে, যাতে অবজেক্টটির দিকে নির্দেশ করা হচ্ছে তার জীবনকাল পরিচালনা করতে। কোনও একক স্মার্ট পয়েন্টার টাইপ নেই, তবে তারা সকলেই ব্যবহারিক উপায়ে কাঁচা পয়েন্টার বিমূর্ত করার চেষ্টা করে try

স্মার্ট পয়েন্টারগুলি কাঁচা পয়েন্টারগুলির চেয়ে বেশি পছন্দ করা উচিত। আপনি যদি মনে করেন যে আপনাকে পয়েন্টারগুলি ব্যবহার করতে হবে (প্রথমে যদি আপনি সত্যিই তা করেন তবে বিবেচনা করুন), আপনি সাধারণত একটি স্মার্ট পয়েন্টার ব্যবহার করতে চান কারণ এটি কাঁচা পয়েন্টারগুলির সাথে অনেকগুলি সমস্যা উপশম করতে পারে, মূলত অবজেক্টটি মুছতে এবং স্মৃতি ফাঁস করতে ভুলে যায়।

কাঁচা পয়েন্টার সহ, প্রোগ্রামারটিকে স্পষ্টভাবে বস্তুটি ধ্বংস করতে হয় যখন এটি আর কার্যকর হয় না।

// Need to create the object to achieve some goal
MyObject* ptr = new MyObject(); 
ptr->DoSomething(); // Use the object in some way
delete ptr; // Destroy the object. Done with it.
// Wait, what if DoSomething() raises an exception...?

তুলনা করে একটি স্মার্ট পয়েন্টার কখন অবজেক্টটি ধ্বংস হয় তা নীতি নির্ধারণ করে। আপনাকে এখনও অবজেক্টটি তৈরি করতে হবে, তবে আপনাকে এটি আর ধ্বংস করার বিষয়ে আর চিন্তা করতে হবে না।

SomeSmartPtr<MyObject> ptr(new MyObject());
ptr->DoSomething(); // Use the object in some way.

// Destruction of the object happens, depending 
// on the policy the smart pointer class uses.

// Destruction would happen even if DoSomething() 
// raises an exception

ব্যবহারে সরলতম নীতিতে স্মার্ট পয়েন্টার র‍্যাপার অবজেক্টের স্কোপ জড়িত থাকে যেমন প্রয়োগ boost::scoped_ptrবা দ্বারা প্রয়োগ করা হয় std::unique_ptr

void f()
{
    {
       std::unique_ptr<MyObject> ptr(new MyObject());
       ptr->DoSomethingUseful();
    } // ptr goes out of scope -- 
      // the MyObject is automatically destroyed.

    // ptr->Oops(); // Compile error: "ptr" not defined
                    // since it is no longer in scope.
}

নোট করুন যে std::unique_ptrদৃষ্টান্তগুলি অনুলিপি করা যায় না। এটি পয়েন্টারটিকে একাধিক বার মুছে ফেলা থেকে বাধা দেয় (ভুলভাবে)। আপনি যাইহোক, আপনি কল করেন এমন অন্য ফাংশনগুলির কাছে এর উল্লেখগুলি পাঠাতে পারেন।

std::unique_ptrs কার্যকর হয় যখন আপনি কোনও নির্দিষ্ট কোডের অবজেক্টের জীবনকাল বেঁধে রাখতে চান বা আপনি যদি কোনও অন্য অবজেক্টের মধ্যে সদস্য ডেটা হিসাবে এম্বেড করে থাকেন তবে other অন্যান্য বস্তুর আজীবন। কোড সহ ধারণকৃত ব্লকটি না বের হওয়া অবধি বা উপস্থিত উপাদানটি নিজেই ধ্বংস না হওয়া অবধি অবজেক্টটি বিদ্যমান।

আরও জটিল স্মার্ট পয়েন্টার নীতিতে পয়েন্টার গণনা করে রেফারেন্স জড়িত। এটি পয়েন্টারটি অনুলিপি করার অনুমতি দেয়। যখন অবজেক্টের সর্বশেষ "রেফারেন্স" নষ্ট হয়ে যায়, বস্তুটি মুছে ফেলা হয়। এই নীতিটি বাস্তবায়ন করেছে boost::shared_ptrএবং দ্বারা std::shared_ptr

void f()
{
    typedef std::shared_ptr<MyObject> MyObjectPtr; // nice short alias
    MyObjectPtr p1; // Empty

    {
        MyObjectPtr p2(new MyObject());
        // There is now one "reference" to the created object
        p1 = p2; // Copy the pointer.
        // There are now two references to the object.
    } // p2 is destroyed, leaving one reference to the object.
} // p1 is destroyed, leaving a reference count of zero. 
  // The object is deleted.

রেফারেন্স গণনা পয়েন্টারগুলি খুব কার্যকর যখন আপনার বস্তুর আজীবন অনেক জটিল হয় এবং কোডের নির্দিষ্ট অংশে বা অন্য কোনও অবজেক্টের সাথে সরাসরি আবদ্ধ না হয়।

রেফারেন্স গণনা পয়েন্টারগুলির মধ্যে একটি অপূর্ণতা রয়েছে - ঝোলা রেফারেন্স তৈরির সম্ভাবনা:

// Create the smart pointer on the heap
MyObjectPtr* pp = new MyObjectPtr(new MyObject())
// Hmm, we forgot to destroy the smart pointer,
// because of that, the object is never destroyed!

আর একটি সম্ভাবনা বিজ্ঞপ্তি রেফারেন্স তৈরি করছে:

struct Owner {
   std::shared_ptr<Owner> other;
};

std::shared_ptr<Owner> p1 (new Owner());
std::shared_ptr<Owner> p2 (new Owner());
p1->other = p2; // p1 references p2
p2->other = p1; // p2 references p1

// Oops, the reference count of of p1 and p2 never goes to zero!
// The objects are never destroyed!

এই সমস্যাটি নিয়ে কাজ করার জন্য, বুস্ট এবং সি ++ 11 উভয়ই weak_ptrএকটিতে দুর্বল (আনসক্টেড) রেফারেন্সটি সংজ্ঞায়িত করার জন্য একটিকে সংজ্ঞায়িত করেছে shared_ptr


7
আপনি কি এর std::auto_ptr<MyObject> p1 (new MyObject());পরিবর্তে মানে std::auto_ptr<MyObject> p1 (new Owner());?
মতিন উলহাক

35
দুর্দান্ত উত্তর। এটি সি ++ 11 এর জন্য আপডেট করা থাকলে ভাল হবে। আমি এই উত্তরটি নতুন 11 স্ট্যান্ডার্ড সম্পর্কে তথ্য সন্ধান করতে পেয়েছি এবং ভবিষ্যতের দর্শকরা আপডেট হওয়া তথ্যটি খুঁজে পেতে পারলে ভাল লাগবে। আমি জানি অটো_পিটারকে হ্রাস করা হয়েছে। আমি বিশ্বাস করি যে বর্ণিত_সিপিআর এবং দুর্বল_সিপিআর বর্ণিত হিসাবে উপস্থিত রয়েছে এবং আমি মনে করি স্কোপড_সিপিআর এখন স্ট্যান্ডার্ডে অনন্য_প্রেটার। যদি এটি সত্য হয় তবে দয়া করে দয়া করে এই উত্তরটি আপডেট করা যাবে?
শৌলব্যাক

16
বলা বাহুল্য একটি ঝুঁকির রেফারেন্স তৈরির সম্ভাবনাটি রেফারেন্স গণনা পয়েন্টারগুলির একটি অপূর্ণতা একেবারে উন্মাদ। সম্ভাব্য ঝোলা রেফারেন্সগুলি কোনও সি ++ পয়েন্টারের একটি অপূর্ণতা । প্রকৃতপক্ষে, স্মার্ট পয়েন্টারগুলি হ্রাস করার উদ্দেশ্যে করা ঠিক এটির অপূর্ণতা
মাইকেল ডারস্ট

16
আপনি যদি স্মার্ট পয়েন্টারটিতে কোনও পয়েন্টার ঘোষণা করেন (উদাহরণে যেমন করা হয়েছিল) আপনি স্মার্ট পয়েন্টারটির সমস্ত সুবিধাকে জেনে রেখে ছেড়ে দিন give এটি কোনও ত্রুটি বা ডিজাইনের ত্রুটি নয়, এটি সর্বাধিক বোকামি ব্যবহারের কল্পনাযোগ্য।
মাইকেল ডারস্ট

3
const std::auto_ptrআপনি সি ++ 03 এর সাথে আটকে থাকলে একটি ব্যবহার করা নিরাপদ। আমি সি ++ 11 এ অ্যাক্সেস না পাওয়া পর্যন্ত আমি এটি পিম্পল প্যাটার্নের জন্য বেশ ব্যবহার করেছি।
টবির স্পিড

302

আধুনিক সি ++ (সি ++ 11 এবং তার পরে) এর এই দিনগুলির জন্য একটি সহজ উত্তর এখানে দেওয়া হয়েছে:

  • স্মার্ট পয়েন্টার কী?
    এটি এমন এক ধরণের যার মানগুলি পয়েন্টারগুলির মতো ব্যবহার করা যেতে পারে তবে এটি স্বয়ংক্রিয় মেমরি পরিচালনার অতিরিক্ত বৈশিষ্ট্য সরবরাহ করে: যখন স্মার্ট পয়েন্টারটি আর ব্যবহার করা হয় না, তখন স্মৃতিটি যে স্মৃতিটিকে নির্দেশ করে তা বাতিল করা হয় ( উইকিপিডিয়ায় আরও বিস্তারিত সংজ্ঞাটি দেখুন )।
  • আমার কখন ব্যবহার করা উচিত?
    কোডে মেমরির একটি অংশের মালিকানা ট্র্যাকিং, বরাদ্দ বা ডি-বরাদ্দ জড়িত; স্মার্ট পয়েন্টারটি প্রায়শই আপনাকে স্পষ্টভাবে এই জিনিসগুলি করার প্রয়োজনীয়তা সংরক্ষণ করে।
  • তবে কোনটি ক্ষেত্রে আমি কোন স্মার্ট পয়েন্টার ব্যবহার করব?
    • std::unique_ptrআপনি যখন একই অবজেক্টের একাধিক রেফারেন্স রাখার পরিকল্পনা করবেন না তখন ব্যবহার করুন । উদাহরণস্বরূপ, এটি মেমোরিটির পয়েন্টারের জন্য ব্যবহার করুন যা কিছু স্কোপে প্রবেশের জন্য বরাদ্দ হয়ে যায় এবং সুযোগ ছাড়ার সময় ডি-বরাদ্দ।
    • std::shared_ptrআপনি যখন একাধিক জায়গা থেকে আপনার অবজেক্টটি উল্লেখ করতে চান তখন ব্যবহার করুন - এবং এই সমস্ত উল্লেখগুলি নিজেরাই না শেষ হওয়া পর্যন্ত আপনার অবজেক্টটিকে ডি-বরাদ্দ করাতে চান না।
    • std::weak_ptrআপনি যখন একাধিক জায়গা থেকে আপনার অবজেক্টটি উল্লেখ করতে চান তখন ব্যবহার করুন - সেই উল্লেখগুলির জন্য যা উপেক্ষা করা এবং হ্রাস করা ঠিক আছে (সুতরাং তারা যখন আপনি ডিফারেন্স করার চেষ্টা করবেন তখন অবজেক্টটি চলে গেছে তা কেবল তারা লক্ষ্য করবেন)।
    • boost::স্মার্ট পয়েন্টারগুলি ব্যবহার করবেন না বা std::auto_ptrবিশেষ ক্ষেত্রে বাদে আপনি যা পড়তে পারেন তা যদি প্রয়োজন হয়।
  • আরে, আমি কোনটি ব্যবহার করতে বলিনি!
    আহ, তবে আপনি সত্যিই এটি চেয়েছিলেন, এটি স্বীকার করুন।
  • তাহলে আমি কখন নিয়মিত পয়েন্টার ব্যবহার করব?
    বেশিরভাগ কোডে যা মেমরির মালিকানা সম্পর্কে অসচেতন। এটি সাধারণত এমন কোনও কার্যক্রমে হয় যা অন্য কোথাও থেকে একটি পয়েন্টার পায় এবং বরাদ্দ দেয় না বা বরাদ্দ দেয় না এবং পয়েন্টারের একটি অনুলিপি সংরক্ষণ করে না যা তাদের কার্য সম্পাদনকে বহির্ভূত করে দেয়।

5
এটি লক্ষণীয় যে স্মার্ট (মালিকানাধীন) পয়েন্টারগুলি সঠিক মেমরি পরিচালনায় সহায়তা করার সময়, কাঁচা (অ-মালিকানা) পয়েন্টারগুলি ডেটা স্ট্রাকচারগুলিতে অন্যান্য সাংগঠনিক উদ্দেশ্যে এখনও কার্যকর। হার্প সুটার সিপ্পিকন ২০১ at এ এই বিষয়ে একটি দুর্দান্ত উপস্থাপনা দিয়েছে, যা আপনি ইউটিউবে দেখতে পাচ্ছেন: সি ++ এ ফাঁস-স্বাধীনতা ... ডিফল্টরূপে।
wiktor.wandachowicz

1
@ wiktor.wandachowicz T*হয় std::unique_ptr<T>কি std::weak_ptr<T>হয়std::shared_ptr<T>
Caleth

@ ক্যালথ: না, আমি এটি বলব না।
einpoklum

1
@ টনিটিয়ানাস: শ্রদ্ধার সাথে - এটি একটি প্রধান সম্পাদনা ছিল; এবং আমি আমার উত্তরটি অনুভব করি না, যা বিমূর্ত, এটির প্রয়োজন। আমি আপনাকে একটি মন্তব্যে এর লিঙ্কে উদাহরণটি পৃথক উত্তর করার পরামর্শ দিচ্ছি।
einpoklum

112

স্মার্ট পয়েন্টার হ'ল একটি পয়েন্টার-জাতীয় টাইপ যা কিছু অতিরিক্ত কার্যকারিতা সহ, যেমন স্বয়ংক্রিয় মেমরি হ্রাস, রেফারেন্স গণনা ইত্যাদি with

স্মার্ট পয়েন্টার পৃষ্ঠাতে ছোট পরিচয় পাওয়া যায় - কী, কেন, কোনটি?

একটি সাধারণ স্মার্ট পয়েন্টার টাইপটি হ'ল std::auto_ptr(সি ++ স্ট্যান্ডার্ডের অধ্যায় 20.4.5), যা মেমরিটিকে সুযোগের বাইরে চলে যাওয়ার পরে স্বয়ংক্রিয়ভাবে হ্রাস করতে দেয় এবং ব্যতিক্রম ছোঁড়ার সময় সরল পয়েন্টার ব্যবহারের চেয়ে আরও দৃ rob় হয় যদিও কম নমনীয়।

আর একটি সুবিধাজনক প্রকার boost::shared_ptrযা রেফারেন্স গণনা কার্যকর করে এবং স্বয়ংক্রিয়ভাবে মেমরিটিকে অবিচ্ছিন্ন করে দেয় যখন অবজেক্টের কোনও রেফারেন্স থাকে না। এটি মেমরি ফাঁস এড়াতে সহায়তা করে এবং আরআইআইআই প্রয়োগ করতে এটি সহজ ।

বিষয়টি ডেভিড ভ্যান্ডেভার্ডে, নিকোলাই এম। জোসুটিস , অধ্যায় 20 অধ্যায়, স্মার্ট পয়েন্টারস "সি ++ টেমপ্লেটস: দ্য কমপ্লিট গাইড" বইয়ের গভীরতার সাথে আচ্ছাদিত রয়েছে । কিছু বিষয় আবৃত:


2
std::auto_ptrআপনি দুর্ঘটনাক্রমে মালিকানা হস্তান্তর করতে পারলে সতর্কতা হ্রাস করা হয় এবং অত্যন্ত নিরুৎসাহিত করা হয়। : - সি ++ 11 বুস্ট, ব্যবহারের প্রয়োজন সরিয়ে ফেলা হবে std::unique_ptr, std::shared_ptrএবংstd::weak_ptr
ninMonkey

42

ক্রিস, সার্জদেব এবং ল্লিওডের দ্বারা প্রদত্ত সংজ্ঞাগুলি সঠিক। আমি সহজ সংজ্ঞা বলে চিহ্নিত করেন যদিও, শুধু আমার জীবনকে সাদাসিধে রাখার: একটি স্মার্ট পয়েন্টার কেবল একটি বর্গ যে overloads -> এবং *অপারেটর। যার মানে আপনার বস্তুর শব্দার্থগতভাবে একটি পয়েন্টার মত দেখায় যে কিন্তু আপনি তা রেফারেন্স কাউন্টিং, স্বয়ংক্রিয় ধ্বংস ইত্যাদি সহ পথ শীতল জিনিস, না করতে পারেন shared_ptrএবং auto_ptrঅধিকাংশ ক্ষেত্রে যথেষ্ট আছে, কিন্তু ছোট idiosyncrasies তাদের নিজস্ব সেট দিয়ে বরাবর আসা।


30

স্মার্ট পয়েন্টারটি নিয়মিত (টাইপযুক্ত) পয়েন্টারের মতো, "চর *" এর মতো, পয়েন্টারটি নিজেই সুযোগের বাইরে চলে যায়, তখন এটি কীটি নির্দেশ করে তা মুছে ফেলাও হয়। আপনি "->" ব্যবহার করে আপনি যেমন নিয়মিত পয়েন্টার চান তেমন এটি ব্যবহার করতে পারেন তবে আপনার যদি ডেটাতে সত্যিকারের পয়েন্টার প্রয়োজন হয় তা নয়। তার জন্য, আপনি "& * পিটিআর" ব্যবহার করতে পারেন।

এটি এর জন্য দরকারী:

  • যে বস্তুগুলি অবশ্যই নতুন দিয়ে বরাদ্দ করা উচিত, তবে আপনি সেই স্ট্যাকের কোনও কিছুর মতো জীবনকাল চান। যদি কোনও জিনিসটি কোনও স্মার্ট পয়েন্টারে নির্ধারিত হয়, তবে প্রোগ্রামটি যখন সেই ফাংশন / ব্লকটি থেকে বেরিয়ে আসে তখন সেগুলি মুছে ফেলা হবে।

  • ক্লাসগুলির ডেটা সদস্যগণ, যাতে অবজেক্টটি মুছে ফেলা হলে ডেস্ট্রাক্টরের কোনও বিশেষ কোড ছাড়াই সমস্ত মালিকানাধীন ডেটাও মুছে ফেলা হয় (আপনার অবশ্যই নিশ্চিত হওয়া দরকার যে ডেস্ট্রাক্টর ভার্চুয়াল, যা প্রায় সবসময়ই করা ভাল) ।

আপনি যখন স্মার্ট পয়েন্টার ব্যবহার করতে চান না তখন:

  • ... পয়েন্টারের আসলে ডেটার মালিক হওয়া উচিত নয় ... অর্থাত্‍ যখন আপনি কেবল ডেটা ব্যবহার করছেন তবে আপনি যেখানে এটি উল্লেখ করছেন সেখানে ফাংশনটি টিকে থাকতে চান।
  • ... স্মার্ট পয়েন্টারটি নিজেই কোনও মুহুর্তে ধ্বংস হবে না। আপনি কখনই এটি স্মৃতিতে বসে না চান যা কখনই ধ্বংস হয় না (যেমন কোনও বস্তু যা গতিযুক্তভাবে বরাদ্দ করা হয় তবে স্পষ্টভাবে মুছে ফেলা হবে না)।
  • ... দুটি স্মার্ট পয়েন্টার একই ডাটাতে নির্দেশ করতে পারে। (তবে, আরও স্মার্ট পয়েন্টার রয়েছে যেগুলি এটি পরিচালনা করবে ... যা রেফারেন্স গণনা বলে is )

আরো দেখুন:


18

বেশিরভাগ ধরণের স্মার্ট পয়েন্টার আপনার জন্য পয়েন্টার-টু অবজেক্টটি নিষ্পত্তি করে। এটি খুব সুবিধাজনক কারণ আপনাকে আর কোনও জিনিস ম্যানুয়ালি নিষ্পত্তি করার বিষয়ে ভাবতে হবে না।

সর্বাধিক ব্যবহৃত স্মার্ট পয়েন্টারগুলি হ'ল std::tr1::shared_ptr(বা boost::shared_ptr), এবং, খুব কম std::auto_ptr,। আমি নিয়মিত ব্যবহারের পরামর্শ দিই shared_ptr

shared_ptrঅত্যন্ত বহুমুখী এবং বিস্তৃত নিষ্পত্তি পরিস্থিতিগুলির সাথে সম্পর্কিত, যেখানে "ডিএলএল সীমানা অতিক্রম করার প্রয়োজন রয়েছে" ( libcআপনার কোড এবং ডিএলএলগুলির মধ্যে যদি বিভিন্ন গুলি ব্যবহার করা হয় তবে সাধারণ দুঃস্বপ্নের ঘটনা ) including


18

স্মার্ট পয়েন্টার হ'ল একটি অবজেক্ট যা পয়েন্টারের মতো কাজ করে তবে অতিরিক্তভাবে নির্মাণ, ধ্বংস, অনুলিপি, চলন এবং নির্ধারণের উপর নিয়ন্ত্রণ সরবরাহ করে control

যে কোনও একটি নিজস্ব স্মার্ট পয়েন্টার বাস্তবায়ন করতে পারে, তবে অনেকগুলি গ্রন্থাগার বিভিন্ন সুবিধা এবং ত্রুটিগুলি সহ প্রতিটি স্মার্ট পয়েন্টার বাস্তবায়ন সরবরাহ করে।

উদাহরণস্বরূপ, বুস্ট নিম্নলিখিত স্মার্ট পয়েন্টার বাস্তবায়ন সরবরাহ করে:

  • shared_ptr<T>Tরেফারেন্স কাউন্ট ব্যবহার করার জন্য পয়েন্টার হ'ল কখন বস্তুর আর প্রয়োজন হয় না তা নির্ধারণ করতে।
  • scoped_ptr<T>সুযোগের বাইরে চলে গেলে এটি একটি পয়েন্টার স্বয়ংক্রিয়ভাবে মোছা হয় scope কোনও অ্যাসাইনমেন্ট সম্ভব নয়।
  • intrusive_ptr<T>অন্য রেফারেন্স গণনা পয়েন্টার। এটি এর চেয়ে ভাল পারফরম্যান্স সরবরাহ করে shared_ptrতবে Tতার নিজস্ব রেফারেন্স গণনা প্রক্রিয়া সরবরাহ করার জন্য ধরণের প্রয়োজন ।
  • weak_ptr<T>একটি দুর্বল পয়েন্টার, shared_ptrবিজ্ঞপ্তি সংক্রান্ত রেফারেন্স এড়ানোর জন্য একত্রে কাজ করে ।
  • shared_array<T>মত shared_ptr, কিন্তু এর অ্যারে জন্য T
  • scoped_array<T>মত scoped_ptr, কিন্তু এর অ্যারে জন্য T

এগুলি প্রতিটিটির একটি মাত্র রৈখিক বিবরণ এবং প্রয়োজন অনুসারে ব্যবহার করা যেতে পারে, আরও বিশদ এবং উদাহরণের জন্য বুস্টের নথিপত্র দেখতে পারেন।

অতিরিক্তভাবে, সি ++ স্ট্যান্ডার্ড লাইব্রেরি তিনটি স্মার্ট পয়েন্টার সরবরাহ করে; std::unique_ptrঅনন্য মালিকানা std::shared_ptrজন্য, ভাগ মালিকানা এবং std::weak_ptrstd::auto_ptrসি ++ 03 তে বিদ্যমান ছিল তবে এখন তা অবচয় করা হয়েছে।


scoped_ptrস্থানীয়ভাবে ঘোষিত কেন নয় তা দয়া করে ব্যাখ্যা করুন const unique_ptr- যা স্কোপটি থেকে বেরিয়ে যাওয়ার পরে মুছে ফেলা হবে।
einpoklum

11

অনুরূপ উত্তরের লিঙ্কটি এখানে: http://sickprogrammersarea.blogspot.in/2014/03/technical-interview-questions-on-c_6.html

স্মার্ট পয়েন্টার হ'ল একটি অবজেক্ট যা সাধারণ পয়েন্টার হিসাবে কাজ করে, দেখায় এবং অনুভব করে তবে আরও কার্যকারিতা সরবরাহ করে। সি ++ এ, স্মার্ট পয়েন্টারগুলি টেম্পলেট শ্রেণি হিসাবে প্রয়োগ করা হয় যা একটি পয়েন্টারকে encapsulate করে এবং স্ট্যান্ডার্ড পয়েন্টার অপারেটরকে ওভাররাইড করে। নিয়মিত পয়েন্টারগুলির তুলনায় তাদের বেশ কয়েকটি সুবিধা রয়েছে। এগুলি নাল পয়েন্টার বা হিপ অবজেক্টের পয়েন্টার হিসাবে শুরু করার গ্যারান্টিযুক্ত। নাল পয়েন্টারের মাধ্যমে ইন্ডিরেশন পরীক্ষা করা হয়। কোনও মুছে ফেলা কখনও প্রয়োজন হয় না। বস্তুর কাছে শেষ পয়েন্টারটি শেষ হয়ে গেলে স্বয়ংক্রিয়ভাবে মুক্ত হয়। এই স্মার্ট পয়েন্টারগুলির সাথে একটি উল্লেখযোগ্য সমস্যা হ'ল নিয়মিত পয়েন্টারগুলির বিপরীতে, তারা উত্তরাধিকারকে সম্মান করে না। পলিমারফিক কোডের জন্য স্মার্ট পয়েন্টারগুলি অপ্রয়োজনীয়। স্মার্ট পয়েন্টার বাস্তবায়নের জন্য নীচে দেওয়া একটি উদাহরণ।

উদাহরণ:

template <class X>
class smart_pointer
{
          public:
               smart_pointer();                          // makes a null pointer
               smart_pointer(const X& x)            // makes pointer to copy of x

               X& operator *( );
               const X& operator*( ) const;
               X* operator->() const;

               smart_pointer(const smart_pointer <X> &);
               const smart_pointer <X> & operator =(const smart_pointer<X>&);
               ~smart_pointer();
          private:
               //...
};

এই শ্রেণিটি এক্স ধরণের একটি অবজেক্টের একটি স্মার্ট পয়েন্টার বাস্তবায়ন করে The এটি কীভাবে ব্যবহার করবেন তা এখানে:

smart_pointer <employee> p= employee("Harris",1333);

অন্যান্য ওভারলোডেড অপারেটরগুলির মতো, পি নিয়মিত পয়েন্টারের মতো আচরণ করবে,

cout<<*p;
p->raise_salary(0.5);

9

http://en.wikipedia.org/wiki/Smart_pointer

কম্পিউটার বিজ্ঞানে, একটি স্মার্ট পয়েন্টার একটি বিমূর্ত ডেটা টাইপ যা স্বয়ংক্রিয় আবর্জনা সংগ্রহ বা সীমানা যাচাইয়ের মতো অতিরিক্ত বৈশিষ্ট্য সরবরাহ করার সময় পয়েন্টারকে সিমুলেট করে। এই অতিরিক্ত বৈশিষ্ট্যগুলি দক্ষতা ধরে রাখার সময় পয়েন্টারগুলির অপব্যবহারের কারণে বাগগুলি হ্রাস করার উদ্দেশ্যে। স্মার্ট পয়েন্টারগুলি সাধারণত মেমরি পরিচালনার উদ্দেশ্যে তাদেরকে নির্দেশ করে এমন বিষয়গুলির উপর নজর রাখে। পয়েন্টারগুলির অপব্যবহার ত্রুটির একটি প্রধান উত্স: ধ্রুবক বরাদ্দ, অবলম্বন এবং রেফারেন্সিং যা পয়েন্টার ব্যবহার করে লিখিত কোনও প্রোগ্রাম দ্বারা সম্পাদন করা আবশ্যক তা সম্ভবত খুব সম্ভবত কিছু স্মৃতি ফাঁস হওয়ার সম্ভাবনা তৈরি করে। স্মার্ট পয়েন্টারগুলি রিসোর্স অবলম্বনটি স্বয়ংক্রিয় করে মেমরি ফাঁস রোধ করার চেষ্টা করে: যখন কোনও বস্তুর প্রতি পয়েন্টার (বা পয়েন্টারগুলির একটি সিরিজের সর্বশেষ) ধ্বংস হয়ে যায়,


6

টি এই টিউটোরিয়ালে একটি শ্রেণি হতে দিন সি ++ তে পয়েন্টারগুলিকে 3 ধরণের মধ্যে ভাগ করা যায়:

1) কাঁচা পয়েন্টার :

T a;  
T * _ptr = &a; 

তারা মেমরির কোনও স্থানে একটি মেমরি ঠিকানা রাখে। সতর্কতার সাথে ব্যবহার করুন, প্রোগ্রামগুলি ট্র্যাক রাখা জটিল হয়ে ওঠে।

স্থির ডেটা বা ঠিকানা সহ পয়েন্টারগুলি back পিছনের দিকে পড়ুন}

T a ; 
const T * ptr1 = &a ; 
T const * ptr1 = &a ;

একটি ডেটা টাইপ টিতে পয়েন্টার যা একটি কনস্ট। মানে আপনি পয়েন্টার ব্যবহার করে ডেটা টাইপ পরিবর্তন করতে পারবেন না। অর্থাত্ *ptr1 = 19; কাজ করবে না. তবে আপনি পয়েন্টারটি সরাতে পারেন। অর্থাত্ ptr1++ , ptr1--; ইত্যাদি কাজ করবে। পিছনের দিকে পড়ুন: টি টাইপ করার জন্য পয়েন্টার যা কনস্টেন্ট

  T * const ptr2 ;

একটি ডেটা টাইপ টি তে একটি কনস্ট পয়েন্টার। মানে আপনি পয়েন্টারটি সরিয়ে নিতে পারবেন না তবে আপনি পয়েন্টারের দ্বারা নির্দেশিত মানটি পরিবর্তন করতে পারবেন। যেমন *ptr2 = 19কাজ করবে কিন্তু ptr2++ ; ptr2--ইত্যাদি কাজ করবে না। পিছনের দিকে পড়ুন: টাইপ টি তে কনস্ট পয়েন্টার

const T * const ptr3 ; 

কনস্টের ডেটা টাইপ টির জন্য একটি কনস্ট পয়েন্টার। মানে আপনি হয় পয়েন্টারটি স্থানান্তর করতে পারবেন না বা ডাটা টাইপ পয়েন্টারটিকে পয়েন্টার হিসাবে পরিবর্তন করতে পারবেন না। অর্থাত্‍ ptr3-- ; ptr3++ ; *ptr3 = 19;কাজ করবে না

3) স্মার্ট পয়েন্টার : #include <memory>}

ভাগ করা পয়েন্টার :

  T a ; 
     //shared_ptr<T> shptr(new T) ; not recommended but works 
     shared_ptr<T> shptr = make_shared<T>(); // faster + exception safe

     std::cout << shptr.use_count() ; // 1 //  gives the number of " 
things " pointing to it. 
     T * temp = shptr.get(); // gives a pointer to object

     // shared_pointer used like a regular pointer to call member functions
      shptr->memFn();
     (*shptr).memFn(); 

    //
     shptr.reset() ; // frees the object pointed to be the ptr 
     shptr = nullptr ; // frees the object 
     shptr = make_shared<T>() ; // frees the original object and points to new object

পয়েন্টার দ্বারা নির্দেশিত বস্তুর দিকে কয়টি "জিনিস" নির্দেশ করে তা ট্র্যাক রাখতে রেফারেন্স কাউন্টিং ব্যবহার করে প্রয়োগ করা হয়েছে। যখন এই গণনা 0 তে চলে যায়, অবজেক্টটি স্বয়ংক্রিয়ভাবে মোছা হয়, অর্থাৎ বস্তুটির দিকে ইশারা করে যখন সমস্ত শেয়ার_পিটার সুযোগের বাইরে চলে যায় তখন আপত্তিটি মুছে ফেলা হয়। আপনি নতুন ব্যবহার করে বরাদ্দ করেছেন এমন অবজেক্টগুলি মুছতে না পারার মাথা ব্যথা থেকে মুক্তি পাওয়া যায়।

দুর্বল পয়েন্টার: ভাগ করা পয়েন্টার ব্যবহার করার সময় উত্থাপিত চক্রীয় রেফারেন্সের সাথে মোকাবিলায় সহায়তা করে যদি আপনার কাছে দুটি ভাগ করে নেওয়া পয়েন্টার দ্বারা চিহ্নিত দুটি বস্তু থাকে এবং একে অপরের সাথে ভাগ করা পয়েন্টারকে নির্দেশ করে একটি অভ্যন্তরীণ ভাগ করা পয়েন্টার থাকে তবে সেখানে একটি চক্রবৃত্ত রেফারেন্স থাকবে এবং অবজেক্টটি হবে না ভাগ করা পয়েন্টারগুলি সুযোগের বাইরে গেলে মুছে ফেলা হবে। এটি সমাধানের জন্য, অভ্যন্তরীণ সদস্যকে একটি ভাগ করা_পিটার থেকে দুর্বল_পিটারে পরিবর্তন করুন। দ্রষ্টব্য: দুর্বল পয়েন্টার ব্যবহার লক () দ্বারা নির্দেশিত উপাদানটি অ্যাক্সেস করতে, এটি একটি দুর্বল_সিপি দেয়।

T a ; 
shared_ptr<T> shr = make_shared<T>() ; 
weak_ptr<T> wk = shr ; // initialize a weak_ptr from a shared_ptr 
wk.lock()->memFn() ; // use lock to get a shared_ptr 
//   ^^^ Can lead to exception if the shared ptr has gone out of scope
if(!wk.expired()) wk.lock()->memFn() ;
// Check if shared ptr has gone out of scope before access

দেখুন: কখন স্টাড :: দুর্বল_পিটার দরকারী?

অনন্য পয়েন্টার: একচেটিয়া মালিকানার সাথে হালকা ওজনের স্মার্ট পয়েন্টার। পয়েন্টারগুলি পয়েন্টারগুলির মধ্যে অবজেক্টগুলি ভাগ না করে অনন্য বস্তুগুলিকে নির্দেশ করার সময় ব্যবহার করুন।

unique_ptr<T> uptr(new T);
uptr->memFn(); 

//T * ptr = uptr.release(); // uptr becomes null and object is pointed to by ptr
uptr.reset() ; // deletes the object pointed to by uptr 

অনন্য পিটিআর দ্বারা নির্দেশিত বস্তুটি পরিবর্তন করতে, স্থানান্তর শব্দার্থক ব্যবহার করুন

unique_ptr<T> uptr1(new T);
unique_ptr<T> uptr2(new T);
uptr2 = std::move(uptr1); 
// object pointed by uptr2 is deleted and 
// object pointed by uptr1 is pointed to by uptr2
// uptr1 becomes null 

তথ্যসূত্র: এগুলি মূলত কনস্ট পয়েন্টার হিসাবে হতে পারে, অর্থাত্ একটি পয়েন্টার যা কনস্ট এবং আরও ভাল বাক্য গঠন সহ সরানো যায় না।

দেখুন: সি ++ এ পয়েন্টার ভেরিয়েবল এবং রেফারেন্স ভেরিয়েবলের মধ্যে পার্থক্যগুলি কী?

r-value reference : reference to a temporary object   
l-value reference : reference to an object whose address can be obtained
const reference : reference to a data type which is const and cannot be modified 

তথ্যসূত্র: https://www.youtube.com/channel/UCEOGtxYTB6vo6MQ-WQ9W_nQ এই প্রশ্নটি দেখানোর জন্য আন্ড্রেকে ধন্যবাদ।


3

স্মার্ট পয়েন্টারটি একটি শ্রেণি, একটি সাধারণ পয়েন্টারের একটি মোড়ক। সাধারণ পয়েন্টারগুলির বিপরীতে, স্মার্ট পয়েন্টের লাইফ সার্কেল একটি রেফারেন্স কাউন্টের উপর ভিত্তি করে (স্মার্ট পয়েন্টার অবজেক্টটি কত সময় নির্ধারিত হয়)। সুতরাং যখনই কোনও স্মার্ট পয়েন্টার অন্যকে বরাদ্দ করা হয়, অভ্যন্তরীণ রেফারেন্স গণনা প্লাস প্লাস। এবং যখনই বস্তুটি সুযোগের বাইরে চলে যায়, রেফারেন্স গণনা বিয়োগ বিয়োগ করে।

স্বয়ংক্রিয় পয়েন্টার, যদিও দেখতে অনুরূপ, স্মার্ট পয়েন্টার থেকে সম্পূর্ণ পৃথক। এটি একটি সুবিধাজনক শ্রেণি যা যখনই কোনও স্বয়ংক্রিয় পয়েন্টার অবজেক্ট পরিবর্তনশীল সুযোগের বাইরে চলে যায় তবে এটি সংস্থানটি হ্রাস করে ates কিছুটা পরিমাণে, এটি একটি পয়েন্টার তৈরি করে (গতিশীলভাবে বরাদ্দ মেমরির জন্য) স্ট্যাক ভেরিয়েবলের মতো কাজ করে (সংকলনের সময় স্থায়ীভাবে বরাদ্দ)।


2

স্মার্ট পয়েন্টারগুলি হ'ল মেমোরি ডি-বরাদ্দ, রিসোর্স ভাগ করে নেওয়া এবং স্থানান্তর সম্পর্কে আপনাকে চিন্তা করতে হবে না।

জাভাতে যে কোনও বরাদ্দ কাজ করে আপনি একইভাবে এই পয়েন্টারগুলি ব্যবহার করতে পারেন। জাভাতে আবর্জনা সংগ্রাহক কৌতুকটি করেন, স্মার্ট পয়েন্টারগুলিতে, কৌশলটি ধ্বংসকারীরা করেন।


1

বিদ্যমান উত্তরগুলি ভাল তবে আপনি যখন সমস্যার সমাধানের চেষ্টা করছেন তার কোনও স্মার্ট পয়েন্টার (সম্পূর্ণ) উত্তর না হলে কী করবেন তা কভার করবেন না।

স্মার্ট পয়েন্টার ব্যবহার করে অন্যান্য জিনিসের মধ্যে (অন্যান্য উত্তরে ভালভাবে ব্যাখ্যা করা) একটি ফাংশন রিটার্ন টাইপ হিসাবে আমরা কীভাবে একটি বিমূর্ত শ্রেণিকে ব্যবহার করব তার একটি সম্ভাব্য সমাধান solution যা এই প্রশ্নের সদৃশ হিসাবে চিহ্নিত করা হয়েছে। তবে, সি ++ এ রিটার্ন টাইপ হিসাবে কোনও বিমূর্ত (বা বাস্তবে যে কোনও) বেস শ্রেণি নির্দিষ্ট করার জন্য প্ররোচিত হয়েছে কিনা জিজ্ঞাসার প্রথম প্রশ্নটি হ'ল "আপনি সত্যিকার অর্থে কী বোঝেন?" বুস্ট পয়েন্টার কনটেইনার লাইব্রেরির ডকুমেন্টেশনে সি ++ (এবং এটি অন্যান্য ভাষার তুলনায় কীভাবে আলাদা) এর আইডিয়োম্যাটিক অবজেক্ট ওরিয়েন্টেড প্রোগ্রামিংয়ের একটি ভাল আলোচনা (আরও রেফারেন্স সহ) রয়েছে There। সংক্ষেপে, সি ++ এ আপনাকে মালিকানা সম্পর্কে ভাবতে হবে। কোন স্মার্ট পয়েন্টারগুলি আপনাকে সাহায্য করে, তবে কেবলমাত্র সমাধান নয়, বা সর্বদা সম্পূর্ণ সমাধান (তারা আপনাকে বহুবর্ষীয় অনুলিপি দেয় না) এবং আপনি আপনার ইন্টারফেসে প্রকাশ করতে চান এমন কোনও সমাধান নয় (এবং কোনও ফাংশন রিটার্ন একটি ভয়াবহ শোনায় অনেকটা ইন্টারফেসের মতো)। উদাহরণস্বরূপ, এটি কোনও রেফারেন্স ফেরত দেওয়ার পক্ষে যথেষ্ট। তবে এই সমস্ত ক্ষেত্রে (স্মার্ট পয়েন্টার, পয়েন্টার ধারক বা কেবল একটি রেফারেন্স ফিরিয়ে দেওয়া) আপনি কোনও মান থেকে রেফারেন্সকে কিছু ফর্ম হিসাবে পরিবর্তন করেছেন । যদি আপনার সত্যিকারের অনুলিপিটির প্রয়োজন হয় তবে আপনাকে অ্যাডোব পলি বা বুস্টের মতো লাইব্রেরি ব্যবহার করে আরও বয়লারপ্লেট "আইডিয়ম" যুক্ত করতে হবে বা সি ++ এ আইওপিএমেটিক (বা অন্যথায়) ওওপি ছাড়িয়ে যেতে হবে ype

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.