সি ++ ১১ টি অনন্য_পিটার এবং ভাগ করা_পিটার কি একে অপরের ধরণের রূপান্তর করতে সক্ষম?


105

নেই সি ++ 11 মান গ্রন্থাগার A থেকে রূপান্তর করতে কোন উপযোগ প্রদান std::shared_ptrকরতে std::unique_ptr, অথবা বিপরীতভাবে ভাইস? এই নিরাপদ অপারেশন?


দয়া করে "নিরাপদ অপারেশন" সংজ্ঞায়িত করুন। আপনি কোন ধরণের সুরক্ষা খুঁজছেন? আজীবন ব্যবস্থাপনার নিরাপত্তা? থ্রেড সুরক্ষা?
— জাগডস্পায়ার

4
"এসটিএল" মানে স্ট্যান্ডার্ড লাইব্রেরি নেই। এসটিএলের কিছু করার নেই shared_ptr।
— কৌতূহলী

4
@jaggedSpire থ্রেড নিরাপত্তা অর্থ হবে আপনি বিভিন্ন থ্রেড ব্যবহৃত মালিক থাকতে, অর্থাত্ ব্যবহারের গণনা না 1.
— curiousguy

পছন্দ করেছেন আমার বক্তব্যটি ছিল "সুরক্ষা" ওপির প্রশ্নে যথাযথভাবে সংজ্ঞায়িত হয়নি এবং একাধিক প্রকারের কারণে তিনি কোন ধরণের "সুরক্ষা" বোঝাতে চেয়েছিলেন তা পরিষ্কার করার দরকার ছিল।
— জাগডস্পায়ার

উত্তর:


172

std::unique_ptrএকচেটিয়া মালিকানা প্রকাশের সি ++ 11 উপায়, তবে এর অন্যতম আকর্ষণীয় বৈশিষ্ট্য হ'ল এটি সহজে এবং দক্ষতার সাথে একটিতে রূপান্তরিত হয় std::shared_ptr।

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

std::shared_ptrকরার std::unique_ptrঅনুমতি নেই। একবার আপনি কোনও উত্সের আজীবন পরিচালনাকে একটিতে পরিণত করার পরে std::shared_ptr, আপনার মন পরিবর্তন হয় না। এমনকি যদি রেফারেন্স গণনা এক হয় তবে আপনি std::unique_ptrএটি পরিচালনা করতে, বলতে, আপনি উত্সটির মালিকানা দাবি করতে পারবেন না ।

তথ্যসূত্র: কার্যকর আধুনিক সি ++। আপনার সি ++ 11 এবং সি ++ 14 এর ব্যবহার উন্নত করার জন্য বিশেষ উপায়। স্কট মায়ার্স

সংক্ষেপে বলতে গেলে, আপনি সহজেই এবং দক্ষতার একটি রূপান্তর করতে পারেন std::unique_ptrকরার std::shared_ptrকিন্তু আপনি রূপান্তর করতে পারবেন না std::shared_ptrকরার std::unique_ptr।

উদাহরণ স্বরূপ:

std::unique_ptr<std::string> unique = std::make_unique<std::string>("test");
std::shared_ptr<std::string> shared = std::move(unique);

বা:

std::shared_ptr<std::string> shared = std::make_unique<std::string>("test");

9
...তুমি এটা কিভাবে কর?
— জেক

4
@ জেক আমি একটি উদাহরণ যুক্ত করেছি
— chema989

সচেতন যে অনুমতি দেওয়া হয় না কম্পাইলার (অন্তত না জিসিসি) প্রকৃতপক্ষে হবে না প্রতিরোধ (অথবা এমনকি সাবধান থাকুন) যদি আপনি দূর্ঘটনাক্রমে (যেমন একজন সদস্য ভেরিয়েবলের পয়েন্টার টাইপ পরিবর্তন করে) একটি দায়িত্ব অর্পণ std::unique_ptrএকটি থেকে std::shared_ptr।
— স্টিফানকিউ


@StefanQ আপনি কি মনে হয় যে এটি একটি দায়িত্ব অর্পণ করা অনুমোদিত নয় তোলে std::unique_ptrএকটি মধ্যে std::shared_ptr? স্ট্যান্ডার্ড লাইব্রেরি একটি মুভ অ্যাসাইনমেন্ট অপারেটরের template<class Y, class Deleter> shared_ptr& operator=(std::unique_ptr<Y, Deleter>&& r); জন্য সংজ্ঞা দেয় std::shared_ptr<T>।
— cuddlebugCuller

-8

ইউনিক_সিপিআর_আপনার দেওয়া হয়েছে, শেয়ারড_পিটার এস_পিটিআর তৈরি করুন:

std::shared_ptr<whatever> s_ptr(u_ptr.release());

অন্য পথে যাওয়া অবৈধ।


29
এখানে "সঠিক" উপায়:std::shared_ptr<whatever> s_ptr(std::move(u_ptr));
— এমলাই

6
এবং এখানে std::shared_ptr<whatever> s_ptr{std::move(u_ptr)};
— পেডেন্টিক

4
এটি সম্পর্কে কম নিরাপদ কি?
— এনএমআর

7
@ ভায়োলেটজিরাফ • আমি মনে করি যে পলিভারটেক্স নতুন সূচনা তালিকা বাক্য গঠনটি ব্যবহার করার পক্ষে পরামর্শ দিচ্ছে - যা নিঃশব্দ সংকীর্ণ রূপান্তরগুলি এড়িয়ে যায় এবং সদস্য আঞ্চলিকতাকে একটি অভিন্ন সিনট্যাক্সের সাথে সামঞ্জস্য করে - এটি প্রবেশের জন্য একটি ভাল অভ্যাস হিসাবে। একজনের ছয়, অন্যের অর্ধ ডজন?
— এলজয়

9
@ এনএমআর এটি অনিরাপদ কারণ আপনি এর Deleterভিতরে থাকা unique_ptr
— সঞ্চয়টি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.