অটো_পিটারকে কেন হতাশ করা হচ্ছে?


উত্তর:


93

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

নামের পরিবর্তনটিও (স্বাগত) একটি স্বাগত - auto_ptrএটি কী কী স্বয়ংক্রিয় করার চেষ্টা করে সে সম্পর্কে আপনাকে সত্যিকার অর্থে খুব বেশি কিছু জানায় না, তবে unique_ptrযা সরবরাহ করা হয়েছে তার মোটামুটি যুক্তিসঙ্গত (যদি ক্ষয়ক্ষতি হয়) বর্ণনা রয়েছে।


25
auto_ptrনামের উপর একটি নোট : স্বয়ংক্রিয়ভাবে স্বয়ংক্রিয় পরিবর্তনশীল হিসাবে স্বয়ংক্রিয় প্রস্তাব দেয় এবং এটি এমন একটি জিনিসকে বোঝায় যা auto_ptrএটির ধ্বংসকারীতে পরিচালিত সংস্থানটিকে ধ্বংস করে (যখন এটি সুযোগের বাইরে চলে যায়)।
ভিনসেঞ্জো পাই পাই

14
আরও তথ্য: অবমূল্যায়নের জন্য এখানে সরকারী যুক্তি রয়েছে auto_ptr: ওপেন-std.org/jtc1/sc22/wg21/docs/papers/2005/…
হাওয়ার্ড

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

4
@ হাই: এর জন্য বিশেষীকরণ std::sortনেই unique_ptr। পরিবর্তে এটি অনুলিপি করার জন্য পুনরায় নির্দিষ্ট করা হয়েছিল। সুতরাং auto_ptrআসলে আধুনিক সঙ্গে কাজ করেsort । কিন্তু সি ++ 98/03 sortএখানে শুধু একটি উদাহরণ অ্যালগরিদম হল: কোন জেনেরিক আলগোরিদিম (এসটিডি-সরবরাহকৃত অথবা ব্যবহারকারীর লেখা) যে কপি সিনট্যাক্স অনুমান রয়েছে কপি শব্দার্থবিদ্যা সম্ভবত যদি সঙ্গে ব্যবহার একটি রান-টাইম এরর থাকবে auto_ptr, কারণ auto_ptrচুপটি প্যাচসমূহ সঙ্গে কপি সিনট্যাক্স। বিষয়টি ন্যায়বিচারের চেয়ে অনেক বড় sort
হাওয়ার্ড হিন্যান্ট

36

আমি বিদ্যমান উত্তরগুলি দুর্দান্ত দেখতে পেয়েছি তবে পয়েন্টারগুলির pov থেকে। আইএমও, একটি আদর্শ উত্তরের ব্যবহারকারীর / প্রোগ্রামারের দৃষ্টিভঙ্গির উত্তর থাকতে হবে।

প্রথম জিনিস (তার উত্তর জেরি কফিন দ্বারা চিহ্নিত হিসাবে)

  • অটো_সিপিটি পরিস্থিতি অনুসারে ভাগ করে নেওয়া_প্টর বা ইউনিক_পিটার দ্বারা প্রতিস্থাপিত হতে পারে

শেয়ারড_পিটার: আপনি যদি রিসোর্স / মেমোরি মুক্ত করার বিষয়ে উদ্বিগ্ন হন এবং যদি আপনার একাধিক ফাংশন রয়েছে যা এটি-ডিফারেন্ট অবজেক্টটি ব্যবহার করতে পারে তবে শেয়ারড_পিটারের সাথে যান।

ডিফারেন্ট-টাইমস দ্বারা, এমন একটি পরিস্থিতির কথা চিন্তা করুন যেখানে অবজেক্ট-পিটিআর একাধিক ডেটা-কাঠামোয় সংরক্ষণ করা হয় এবং পরে অ্যাক্সেস করা হয়। একাধিক থ্রেড অবশ্যই অন্য উদাহরণ।

অনন্য_পিটার: আপনি যদি উদ্বিগ্ন সকলেই মেমরি মুক্ত করে থাকেন এবং অবজেক্টের অ্যাক্সেস সিকিউএনটিয়াল হয়, তবে অনন্য_প্ট্রারের জন্য যান।

সিকোয়েনশিয়াল দ্বারা, আমি বলতে চাইছি যে কোনও বিন্দুতে একটি প্রসঙ্গ থেকে অবজেক্ট অ্যাক্সেস করা হবে। উদাহরণস্বরূপ এমন একটি বস্তু যা তৈরি করা হয়েছিল এবং স্রষ্টার দ্বারা সৃষ্টির সাথে সাথেই ব্যবহৃত হয়েছিল। তৈরির পরে অবজেক্টটি FIRST ডেটা স্ট্রাকচারে সংরক্ষণ করা হয় । তারপরে হয় কোনওটি ডেটা-স্ট্রাকচারের পরে অবজেক্টটি ধ্বংস হয়ে যায় বা SECOND ডেটা স্ট্রাকচারে স্থানান্তরিত হয় ।

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

অটো_সিপিটারকে কেন স্মার্ট পয়েন্টারের পক্ষে অবমূল্যায়ন করা হয়েছিল তার একমাত্র গুরুত্বপূর্ণ কারণ হ'ল অ্যাসাইনমেন্ট-শব্দার্থবিজ্ঞান যদি সে কারণ না না হয় তবে তারা অমিত_পট্রিকে নতুন পদক্ষেপের পরিবর্তে অটো_পিটার যুক্ত করত। যেহেতু অ্যাসাইনমেন্ট-শব্দার্থবিজ্ঞানগুলি অত্যন্ত অপছন্দযোগ্য বৈশিষ্ট্য, তাই তারা চাইছিল যে এই বৈশিষ্ট্যটি চলে যেতে পারে, তবে যেহেতু কোড লেখা আছে যা শব্দার্থক শব্দগুলির ব্যবহার করে (যা মান-কমিটি পরিবর্তন করতে পারে না), তাদের পরিবর্তে তাদের অটো_পিটার ছেড়ে যেতে হয়েছিল এটি পরিবর্তন।

লিঙ্কটি থেকে: http://www.cplusplus.com/references/memory/unique_ptr/operator=/

আনকিউ_প্ট্রার দ্বারা সমর্থিত বিভিন্ন ধরণের অ্যাসাইনমেন্ট

  • সরানো অ্যাসাইনমেন্ট (1)
  • নাল পয়েন্টার বরাদ্দ করুন (2)
  • টাইপ-কাস্ট অ্যাসাইনমেন্ট (3)
  • অনুলিপি নিয়োগ (মুছে ফেলা!) (4)

থেকে: http://www.cplusplus.com/references/memory/auto_ptr/operator=/

Auto_ptr দ্বারা সমর্থিত বিভিন্ন ধরণের অ্যাসাইনমেন্ট

  • অনুলিপি নিয়োগ (4) অপরাধী

এখন অনুলিপি কার্যভারটি কেন নিজেকে এতই অপছন্দ করেছিল সেই কারণটিতে এসে আমার এই তত্ত্বটি রয়েছে:

  1. সমস্ত প্রোগ্রামার বই বা মান পড়েন না
  2. এর মুখোমুখি অটো_পিটার, আপনাকে অবজেক্টটির মালিকানা দেওয়ার প্রতিশ্রুতি দেয়
  3. অল্প_ * (শুল্কযুক্ত), অটো_পিটারের ধারা, যা সমস্ত প্রোগ্রামারদের দ্বারা পড়া হয় না, অনুমতি দেয়, একটি অটো_সিপিটারকে অন্যটিতে অ্যাসাইনমেন্ট দেয় এবং মালিকানা স্থানান্তর করে।
  4. গবেষণা দেখিয়েছে যে এই ব্যবহারটি সমস্ত ব্যবহারের 3.1415926535% এর জন্য, এবং অন্য ক্ষেত্রে অনিচ্ছাকৃত।

অনিচ্ছাকৃত আচরণটি সত্যই অপছন্দ এবং অতএব অটো_পিটারের জন্য অপছন্দ।

(3.1415926536% প্রোগ্রামার যারা ইচ্ছাকৃতভাবে মালিকানা সি ++ 11 এ স্থানান্তর করতে চান তাদের স্ট্যান্ড :: পদক্ষেপ () দিয়েছিলেন, যা কোডটি পড়তে এবং বজায় রাখতে যাওয়া সমস্ত ইন্টার্নের জন্য তাদের উদ্দেশ্য স্ফটিক স্পষ্ট করে তুলেছে।)


4
যেহেতু আপনি কখনো দুই চান auto_ptrএকই বস্তুর নির্দেশিত মান (যেহেতু তারা ভাগ করা হয়নি দিতে পারি মালিকানা ডাই প্রথম এক প্রাণঘাতী ঐতিহ্য সঙ্গে অন্যান্য ছাড়বে; এটাও জন্য সত্য unique_ptrব্যবহার), আপনি পরামর্শ দিতে পারেন কি হয়েছিল মধ্যে অভিপ্রেত বাকি সমস্ত ব্যবহারের 96.8584073465%?
মার্ক ভ্যান লিউউয়েন

তাদের সবার জন্য কথা বলতে পারে না, তবে আমি অনুমান করব, তারা মনে করবে যে বস্তুর মালিকানা সরানো হচ্ছে এবং কেবল নকল করা হয়নি, যা ভুল।
অজিত গঙ্গা

@ অজিৎগঙ্গা নিম্নোক্ত বাক্যটিতে 'সামান্য- * (শুল্কের উদ্দেশ্যে)', আপনি "শ্লেষের উদ্দেশ্যে" হিসাবে উল্লেখ করেছেন। এই কথাটি আমার জন্য নতুন এবং যেভাবেই আমি এটি গুগল করে জানতে পেরেছিলাম যে এখানে কিছু রসিকতা রয়েছে যা উদ্দেশ্যমূলকভাবে এখানে করা হয়েছিল was এখানে কি রসিকতা? এটা জানতে আগ্রহী।
ভিনথ এনারজিটিক

@ অজিৎগঙ্গা আপনি 'লিটল- * (শঙ্কিত উদ্দেশ্য), অটো_পিটারের ধারাটির মতো উল্লেখ করেছেন, যা সমস্ত প্রোগ্রামারদের দ্বারা পড়া হয় না, অনুমতি দেয়, একটি অটো_সিপিটারকে অন্যটিতে অ্যাসাইনমেন্ট দেয় এবং মালিকানা হস্তান্তর করে'। ধরা যাক যে পূর্ণসংখ্যা হিসাবে আমার কাছে দুটি অটো পিটিআর এবং বি আছে। আমি অ্যাসাইনমেন্টটি করছি কারণ *a=*b;এখানে শুধু খ এর মান কপি করা আছে। আমি আশা করি ক এবং খ উভয়ের মালিকানা এখনও একই লোকের কাছে রয়েছে। আপনারা উল্লেখ করেছেন যে owণশিপ স্থানান্তরিত হবে। এটা কেমন হবে?
ভিনথ এনারজিটিক

@ ভিনোথেনার্জিটিক অজিৎ auto_ptrনিজেই কোনও বস্তুকে বরাদ্দ দেওয়ার বিষয়ে কথা বলছিলেন । এর নির্দেশিত মানটিকে / থেকে নির্ধারিত করার উপর মালিকানার কোনও প্রভাব নেই, বা তার সাথে প্রাসঙ্গিকতা নেই। আমি আশা করি আপনি এখনও ব্যবহার করছেন না auto_ptr?
আন্ডারস্কোর_

23

shared_ptrপাত্রে ভিতরে সংরক্ষণ করা যেতে পারে। auto_ptrপারি না

BTW unique_ptrসত্যিই সরাসরি করা হয় auto_ptrপ্রতিস্থাপন, এটি উভয় শ্রেষ্ঠ বৈশিষ্ট্য সম্মিলন std::auto_ptrএবং boost::scoped_ptr


11

তবুও আরেকটি পার্থক্য ব্যাখ্যা করে ....

কার্যকরীভাবে, সি ++ 11 std::unique_ptrহ'ল "স্থির" std::auto_ptr: উভয়ই উপযুক্ত যখন - কার্যকর করার সময় যে কোনও সময় - পয়েন্ট-টু অবজেক্টের জন্য একক স্মার্ট-পয়েন্টার মালিক থাকা উচিত।

গুরুত্বপূর্ণ পার্থক্যটি হ'ল =>নীচের লাইনে প্রদর্শিত অন্য অন-মেয়াদোত্তীর্ণ স্মার্ট পয়েন্টার থেকে অনুলিপি-নির্মাণ বা কার্যনির্বাহীকরণ :

   std::auto_ptr<T> ap(...);
   std::auto_ptr<T> ap2(get_ap_to_T());   // take expiring ownership
=> std::auto_ptr<T> ap3(ap);  // take un-expiring ownership ala ap3(ap.release());
   ap->xyz;  // oops... can still try to use ap, expecting it to be non-NULL

   std::unique_ptr<T> up(...);
   std::unique_ptr<T> up2(get_up_to_T());   // take expiring ownership
=> std::unique_ptr<T> up3(up);  // COMPILE ERROR: can't take un-expiring ownership
=> std::unique_ptr<T> up4(std::move(up));  // EXPLICIT code allowed
=> std::unique_ptr<T> up4(up.release());   // EXPLICIT code allowed

উপরে, ap3একটিতে সেট করে *apরেখে চুপচাপ মালিকানাটির "চুরি" করা এবং সমস্যাটি খুব সহজেই ঘটতে পারে, প্রোগ্রামার তার সুরক্ষার কথা চিন্তা না করেই করে।apnullptr

উদাহরণস্বরূপ, একটি যদি class/ structটি std::auto_ptrসদস্য, তারপর উপার্জন একটি দৃষ্টান্ত একটি কপি হবে releaseঅনুলিপি করা হচ্ছে উদাহরণস্বরূপ থেকে পয়েন্টার: যেমন যে অদ্ভুত এবং বিপজ্জনকভাবে বিভ্রান্তিকর শব্দার্থবিদ্যা সাধারণত কিছু কপি এটি পরিবর্তন করা হয় না। শ্রেণি / কাঠামো লেখকের পক্ষে আক্রমণকারী এবং রাষ্ট্র সম্পর্কে বিতর্ক করার সময় পয়েন্টারটির প্রকাশকে উপেক্ষা করা এবং ফলস্বরূপ নালার সময় ঘটনাক্রমে স্মার্ট-পয়েন্টারটিকে অবজ্ঞা করার চেষ্টা করা বা কেবলমাত্র পয়েন্ট-টু ডেটার অ্যাক্সেস / মালিকানা প্রত্যাশিত নয়।


অটো_পিটার নিঃশব্দে "চুরি করে" মালিকানা +1
ক্যামিনো

3

auto_ptr STL পাত্রে ব্যবহার করা যাবে না কারণ এটি একটি কপি কন্সট্রাকটর যে ধারক প্রয়োজনীয়তা পূরণ করতে পারছে না হয়েছে CopyConstructible । অনন্য_পিটার একটি অনুলিপি নির্মাণকারী কার্যকর করে না, তাই পাত্রে বিকল্প পদ্ধতি ব্যবহার করা হয়। অনন্য_পিটারটি পাত্রে ব্যবহার করা যেতে পারে এবং স্ট্যান্ড অ্যালগরিদমের জন্য ভাগ করা_পিটারের চেয়ে দ্রুত।

#include <iostream>
#include <type_traits>
#include <vector>
#include <memory>

using namespace std;

int main() {
  cout << boolalpha;
  cout << "is_copy_constructible:" << endl;
  cout << "auto_ptr: " << is_copy_constructible< auto_ptr<int> >::value << endl;
  cout << "unique_ptr: " << is_copy_constructible< unique_ptr<int> >::value << endl;
  cout << "shared_ptr: " << is_copy_constructible< shared_ptr<int> >::value << endl;

  vector<int> i_v;
  i_v.push_back(1);
  cout << "i_v=" << i_v[0] << endl;
  vector<int> i_v2=i_v;
  cout << "i_v2=" << i_v2[0] << endl;

  vector< unique_ptr<int> > u_v;
  u_v.push_back(unique_ptr<int>(new int(2)));
  cout << "u_v=" << *u_v[0] << endl;
  //vector< unique_ptr<int> > u_v2=u_v;  //will not compile, need is_copy_constructible == true
  vector< unique_ptr<int> > u_v2 =std::move(u_v);  // but can be moved
  cout << "u_v2=" << *u_v2[0] << " length u_v: " <<u_v.size() << endl;

  vector< shared_ptr<int> > s_v;
  shared_ptr<int> s(new int(3));
  s_v.push_back(s);
  cout << "s_v=" << *s_v[0] << endl;
  vector< shared_ptr<int> > s_v2=s_v;
  cout << "s_v2=" << *s_v2[0] << endl;

  vector< auto_ptr<int> > a_v;  //USAGE ERROR

  return 0;
}

>cxx test1.cpp -o test1
test1.cpp: In function âint main()â:
test1.cpp:33:11: warning: âauto_ptrâ is deprecated (declared at /apps/hermes/sw/gcc/gcc-4.8.5/include/c++/4.8.5/backward/auto_ptr.h:87) [-Wdeprecated-declarations]
   vector< auto_ptr<int> > a_v;  //USAGE ERROR
           ^
>./test1
is_copy_constructible:
auto_ptr: false
unique_ptr: false
shared_ptr: true
i_v=1
i_v2=1
u_v=2
s_v=3
s_v2=3
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.