স্ট্যান্ড :: অনন্য_পিটার কীভাবে ঘোষণা করবেন এবং এর ব্যবহার কী?


95

আমি কীভাবে std::unique_ptrকাজ করে তা বোঝার চেষ্টা করি এবং এর জন্য আমি এই দস্তাবেজটি পেয়েছি । লেখক নিম্নলিখিত উদাহরণ থেকে শুরু:

#include <utility>  //declarations of unique_ptr
using std::unique_ptr;
// default construction
unique_ptr<int> up; //creates an empty object
// initialize with an argument
unique_ptr<int> uptr (new int(3));
double *pd= new double;
unique_ptr<double> uptr2 (pd);
// overloaded * and ->
*uptr2 = 23.5;
unique_ptr<std::string> ups (new std::string("hello"));
int len=ups->size();

আমার কাছে যা বিভ্রান্তিকর তা এই লাইনে

unique_ptr<int> uptr (new int(3));

আমরা পূর্ণসংখ্যা হিসাবে (বৃত্তাকার বন্ধনীগুলির মধ্যে) এবং এখানে ব্যবহার করি

unique_ptr<double> uptr2 (pd);

আমরা একটি যুক্তি হিসাবে একটি পয়েন্টার ব্যবহার। এটা কি কোনো পার্থক্য তৈরি করে?

আমার কাছে যা স্পষ্ট নয়, পয়েন্টারগুলি কীভাবে এইভাবে ঘোষিত হয়েছে এটি একটি "সাধারণ" উপায়ে ঘোষিত পয়েন্টার থেকে আলাদা হবে।


13
new int(3)নতুনকে একটি পয়েন্টার দেয় int, ঠিক যেমনটি pdনতুনের জন্য একটি পয়েন্টার ছিল double
ডেভিড শোয়ার্জ

উত্তর:


89

এর unique_ptr<T>নির্মাতা প্রকারের কোনও বস্তুতে কাঁচা পয়েন্টার গ্রহণ করে T(সুতরাং এটি গ্রহণ করে T*)।

প্রথম উদাহরণে:

unique_ptr<int> uptr (new int(3));

পয়েন্টারটি একটি newঅভিব্যক্তির ফলাফল , যখন দ্বিতীয় উদাহরণে:

unique_ptr<double> uptr2 (pd);

পয়েন্টারটি pdভেরিয়েবলে সংরক্ষণ করা হয় ।

ধারণাগতভাবে, কোনও পরিবর্তন হয় না (আপনি unique_ptrএকটি কাঁচা পয়েন্টার থেকে একটি নির্মাণ করছেন ), তবে দ্বিতীয় পদ্ধতিটি সম্ভবত আরও বিপজ্জনক, যেহেতু এটি আপনাকে উদাহরণস্বরূপ করার অনুমতি দেয়:

unique_ptr<double> uptr2 (pd);
// ...
unique_ptr<double> uptr3 (pd);

সুতরাং দুটি অনন্য পয়েন্টার রয়েছে যা কার্যকরভাবে একই বস্তুকে আবদ্ধ করে তোলে (এইভাবে একটি অনন্য পয়েন্টারের শব্দার্থ লঙ্ঘন )।

এ কারণেই যখন সম্ভব হয় তখন অনন্য পয়েন্টার তৈরির জন্য প্রথম ফর্মটি আরও ভাল। লক্ষ্য করুন, C ++ 14 এ আমরা সক্ষম হব:

unique_ptr<int> p = make_unique<int>(42);

যা পরিষ্কার এবং নিরাপদ উভয়ই। আপনার এই সন্দেহ সম্পর্কে:

আমার কাছে যা স্পষ্ট নয়, পয়েন্টারগুলি কীভাবে এইভাবে ঘোষিত হয়েছে এটি একটি "সাধারণ" উপায়ে ঘোষিত পয়েন্টার থেকে আলাদা হবে।

স্মার্ট পয়েন্টারগুলি অবজেক্টের মালিকানার মডেল করার কথা বলে এবং স্বয়ংক্রিয়ভাবে পয়েন্টারটি যখন অবজেক্টের সর্বশেষ (স্মার্ট, মালিকানাধীন) পয়েন্টারটি সুযোগের বাইরে চলে যায় তখন বিন্দু বস্তুটি ধ্বংস করার যত্ন নেয় care

এইভাবে আপনাকে deleteগতিশীলভাবে বরাদ্দকৃত বস্তুগুলিতে করা মনে রাখবেন না - স্মার্ট পয়েন্টারটির ধ্বংসকারী এটি আপনার জন্য করবেন - বা ইতিমধ্যে ধ্বংস হওয়া কোনও বস্তুর প্রতি আপনি (ঝুঁকিপূর্ণ) পয়েন্টারকে অবজ্ঞাপূর্ণ করবেন না কিনা তা নিয়ে চিন্তা করতে হবে:

{
    unique_ptr<int> p = make_unique<int>(42);
    // Going out of scope...
}
// I did not leak my integer here! The destructor of unique_ptr called delete

এখন unique_ptrএকটি স্মার্ট পয়েন্টার যা অনন্য মালিকানার মডেল করে, এর অর্থ হল যে আপনার প্রোগ্রামে যে কোনও সময় পয়েন্ট পয়েন্টটির জন্য কেবলমাত্র একটি (মালিকানাধীন) পয়েন্টার থাকতে পারে - এজন্যই unique_ptrঅনুলিপিযোগ্য নয়।

যতক্ষণ আপনি স্মার্ট পয়েন্টারগুলি এমনভাবে ব্যবহার করেন যা আপনার মেনে চলার জন্য জড়িত চুক্তিটি ভঙ্গ করে না, আপনার গ্যারান্টি থাকবে যে কোনও স্মৃতি ফাঁস হবে না এবং আপনার অবজেক্টের জন্য যথাযথ মালিকানা নীতি কার্যকর করা হবে। কাঁচা পয়েন্টারগুলি আপনাকে এই গ্যারান্টি দেয় না।


4
হাই, আমি সম্পর্কে কিছু বুঝতে পারলাম না model object ownership, integer leakকোড বা মধ্যে enforcing ownership policy for object। আপনি এই ধারণাটি শিখতে দয়া করে বিষয় / সংস্থানগুলি প্রস্তাব দিতে পারেন?
উডুনের শিখা

4
unique_ptrত্রুটি না পেয়ে আমি ব্যবহার করতে পারি না : The text ">" is unexpected. It may be that this token was intended as a template argument list terminator but the name is not known to be a template.যদিও আমার আছে #include <utility>এবং আছে #include <memory>। কোন পরামর্শ?
বেনামে

15

অনন্য_পট্রিকে নিয়োগের উভয় ধারণা নিয়ে কাজ করার কোনও পার্থক্য নেই।

int* intPtr = new int(3);
unique_ptr<int> uptr (intPtr);

অনুরূপ

unique_ptr<int> uptr (new int(3));

এখানে অনন্য_পিটার স্বয়ংক্রিয়ভাবে দখল করা স্থান মুছে ফেলবেuptr


এইভাবে ঘোষিত পয়েন্টারগুলি কীভাবে "সাধারণ" উপায়ে ঘোষিত পয়েন্টার থেকে আলাদা হবে।

যদি আপনি হ্যাপ স্পেসে একটি পূর্ণসংখ্যা তৈরি করেন ( নতুন কীওয়ার্ড বা ম্যালোক ব্যবহার করে ), তবে আপনাকে সেই স্মৃতি নিজের থেকে সাফ করতে হবে ( যথাক্রমে মুছুন বা বিনামূল্যে ব্যবহার করে)।

নীচের কোডে,

int* heapInt = new int(5);//initialize int in heap memory
.
.//use heapInt
.
delete heapInt;

এখানে, হিপ আইন্টটি মুছে ফেলতে হবে , এটি ব্যবহার করা হয়ে গেলে। যদি এটি মুছে না যায়, তবে মেমরি ফুটো হয়।

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


10

স্বতন্ত্র পয়েন্টারগুলি যখন সুযোগ থেকে দূরে যায় তারা যে বস্তুটি পরিচালনা করে তা ধ্বংস করার গ্যারান্টিযুক্ত। http://en.cppreferences.com/w/cpp/memory/unique_ptr

এক্ষেত্রে:

unique_ptr<double> uptr2 (pd);

pduptr2সুযোগের বাইরে গেলে ধ্বংস হয়ে যাবে। এটি স্বয়ংক্রিয়ভাবে মোছার মাধ্যমে মেমরি পরিচালনার সুবিধা দেয়।

কেস unique_ptr<int> uptr (new int(3));পয়েন্টারটি এখানে কোনও ভেরিয়েবলের জন্য বরাদ্দ করা ব্যতীত এর ক্ষেত্রে আলাদা নয়।


-1

সিপ্রেফারেন্স থেকে , std::unique_ptrকনস্ট্রাক্টরগুলির মধ্যে একটি

সুস্পষ্ট অনন্য_পিটার (পয়েন্টার পি) নম্বরে;

সুতরাং একটি নতুন তৈরি করা std::unique_ptrহয় এটির কনস্ট্রাক্টরের একটি পয়েন্টার পাস করা।

unique_ptr<int> uptr (new int(3));

বা এটি হিসাবে একই

int *int_ptr = new int(3);
std::unique_ptr<int> uptr (int_ptr);

ভিন্নটি হ'ল এটি ব্যবহারের পরে আপনাকে পরিষ্কার করতে হবে না। আপনি যদি std::unique_ptr(স্মার্ট পয়েন্টার) ব্যবহার না করেন তবে আপনাকে এটি এভাবে মুছতে হবে

delete int_ptr;

যখন আপনার আর এটির প্রয়োজন হয় না বা এটি মেমরি ফুটে উঠবে।

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