আমার কি পুরো পন্যগুলি বা পাত্রে পয়েন্টারগুলিকে স্টোরেজ রাখতে হবে?


162

স্ক্র্যাচ থেকে একটি নতুন সিস্টেম ডিজাইন করা। আমি এসটিএলকে নির্দিষ্ট দীর্ঘ-লাইভ অবজেক্টের তালিকা এবং মানচিত্র সঞ্চয় করতে ব্যবহার করব।

প্রশ্ন: আমি কি আমার এসটিএল ধারকগুলির মধ্যে আমার অবজেক্টের অনুলিপি নির্মাণকারী এবং বস্তুর অনুলিপিগুলি সংরক্ষণ করতে পারি, বা জীবন ও সুযোগটি নিজেই পরিচালনা করা এবং কেবল আমার এসটিএল কনটেইনারগুলিতে কেবল পয়েন্টারগুলি সঞ্চয় করা ভাল?

আমি বুঝতে পারি যে এটি বিশদে কিছুটা সংক্ষিপ্ত, তবে আমি যদি উপস্থিত থাকি তবে "তাত্ত্বিক" আরও ভাল উত্তর খুঁজছি, যেহেতু আমি জানি যে এই উভয় সমাধানই সম্ভব।

পয়েন্টারের সাথে খেলতে দু'টি সুস্পষ্ট অসুবিধা: ১) আমাকে এসটিএল ছাড়িয়ে নিজেকে এই বিষয়গুলির বরাদ্দ / অবলম্বন পরিচালনা করতে হবে। 2) আমি স্ট্যাকের উপর কোনও অস্থায়ী বস্তু তৈরি করতে এবং এটি আমার পাত্রে যুক্ত করতে পারি না।

আমি আর কিছু মিস করছি?


36
god
শ্বর

2
আর একটি মজার বিষয় হ'ল আমাদের যাচাই করা উচিত যে পয়েন্টারটি আসলে সংগ্রহের সাথে যুক্ত হয়েছিল এবং এটি যদি না হয় তবে আমরা সম্ভবত মেমরি ফাঁস এড়াতে মুছুন বলে ডাকি ... যদি ((set.insert (পয়েন্টার))। দ্বিতীয় = মিথ্যা) {ডিলিট পয়েন্টার;}
javapowered

উত্তর:


68

যেহেতু লোকেরা পয়েন্টার ব্যবহারের দক্ষতার দিকে ঝুঁকছে।

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

ওহো, আপডেটগুলি যদি সাধারণ স্টোর পয়েন্টার হয় তবে অনুলিপি / স্থানান্তরের ব্যয়গুলি সাশ্রয় করবে।


7
ক্যাশে লোকালটির ক্ষেত্রে, পয়েন্টটিগুলির জন্য কাস্টম বরাদ্দকারীর পাশাপাশি ভেক্টরে পয়েন্টার সংরক্ষণ করা কার্যকর হতে পারে। কাস্টম বরাদ্দকারীকে ক্যাশের লোকালটির যত্ন নিতে হবে, উদাহরণস্বরূপ নতুন স্থান ব্যবহার করা ( en.wikedia.org/wiki/Placement_syntax#Custom_allocators দেখুন )।
amit

47

এটি সত্যই আপনার পরিস্থিতির উপর নির্ভর করে।

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

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

যদি আপনি অবজেক্টে পয়েন্টার ব্যবহার করার সিদ্ধান্ত নেন তবে বুস্ট পয়েন্টার কনটেইনার লাইব্রেরিটি একবার দেখুন । এই বুস্ট লাইব্রেরিটি সমস্ত এসটিএল কনটেইনারকে গতিশীলভাবে বরাদ্দকৃত বস্তুগুলির সাথে ব্যবহারের জন্য মোড়ক করে।

প্রতিটি পয়েন্টার ধারক (উদাহরণস্বরূপ ptr_vector) কোনও বস্তুটির ধারকটিতে যুক্ত হওয়ার পরে তার মালিকানা গ্রহণ করে এবং আপনার জন্য objects অবজেক্টগুলির আজীবন পরিচালনা করে। আপনি রেফারেন্স দ্বারা একটি পিটিআর_ ধারক সমস্ত উপাদান অ্যাক্সেস। এটি আপনাকে পছন্দ মতো জিনিস করতে দেয়

class BigExpensive { ... }

// create a pointer vector
ptr_vector<BigExpensive> bigVector;
bigVector.push_back( new BigExpensive( "Lexus", 57700 ) );
bigVector.push_back( new BigExpensive( "House", 15000000 );

// get a reference to the first element
MyClass& expensiveItem = bigList[0];
expensiveItem.sell();

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

ধারকটিতে পয়েন্টারের মালিকানা কলারে স্থানান্তরিত করার সুবিধাও রয়েছে (বেশিরভাগ পাত্রে রিলিজ ফাংশনের মাধ্যমে)।


38

যদি আপনি পলিম্পোরিক অবজেক্টগুলি সংরক্ষণ করেন তবে আপনাকে সর্বদা বেস ক্লাস পয়েন্টারগুলির একটি সংগ্রহ ব্যবহার করা উচিত।

এটি হ'ল যদি আপনি আপনার সংগ্রহে বিভিন্ন উদ্ভূত প্রকারের সংরক্ষণের পরিকল্পনা করেন তবে আপনাকে অবশ্যই পয়েন্টারগুলি সংরক্ষণ করতে হবে বা কাটা ডিমন দ্বারা খাওয়া হবে।


1
আমি কাটা ডিমন পছন্দ করতাম!
আইডিচেকপ

22

ইভেন্টের পরে 3 বছরের মধ্যে লাফ দেওয়ার জন্য দুঃখিত, তবে এখানে একটি সতর্কতা নোট ...

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

আমার বর্তমান বড় প্রকল্পে, আমার কেন্দ্রীয় তথ্য কাঠামো মোটামুটি সোজা জিনিসগুলির একটি সেট। প্রকল্পের প্রায় এক বছর (যা আজকের দিনে ঘটে), আমি বুঝতে পেরেছিলাম যে বস্তুটি আসলে বহুকর্মী হওয়া দরকার। নেটে ফিরে এই থ্রেডটি খুঁজে পেয়েছি এবং বুস্ট পয়েন্টার কনটেইনার লাইব্রেরিতে নিকটির লিঙ্কটি খুঁজে পেয়েছে। সবকিছু ঠিক করার জন্য আমাকে শেষ বারে এটিই লিখতে হয়েছিল, তাই এবার আমি এটিকে একবার ঘুরে দেখব।

নৈতিক, যাইহোক, আমার জন্য: যদি আপনার বৈশিষ্টটি পাথরটিতে 100% নিক্ষিপ্ত না হয় তবে পয়েন্টারগুলির জন্য যান এবং আপনি সম্ভবত পরে নিজেকে অনেক কাজ বাঁচাতে পারেন।


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

আপনি ভেন্ডারে মান শব্দার্থক জিনিসটি রেখে আইটেমটি রেখে দিতে পারতেন এবং ভিতরে বহুভোজী আচরণ করতেন।
বিলি ওনিল

19

উভয় বিশ্বের সেরাটি কেন পাবেন না: স্মার্ট পয়েন্টারগুলির একটি ধারক (যেমন boost::shared_ptrবা std::shared_ptr) করুন। আপনাকে মেমরিটি পরিচালনা করতে হবে না, এবং আপনাকে বড় কপি অপারেশনগুলির সাথে ডিল করতে হবে না।


বুস্ট পয়েন্টার কনটেইনার লাইব্রেরি ব্যবহার করে নিক হাদাদাদের পরামর্শ অনুসারে এই পদ্ধতির থেকে কীভাবে আলাদা?
থারস্টেন শেনিং

10
@ ThorstenSchöning std :: shared_ptr বাড়াতে নির্ভরতা যুক্ত করে না।
জেমস জনস্টন

আপনি আপনার পলিমারফিজমটি পরিচালনা করতে ভাগ করে নেওয়া পয়েন্টার ব্যবহার করতে পারবেন না যাতে আপনি অবশেষে এই পদ্ধতির সাথে এই বৈশিষ্ট্যটি মিস করতে পারেন, যদি না আপনি স্পষ্টভাবে পয়েন্টারগুলি না ফেলে থাকেন
auserdude

11

সাধারনত, সবচেয়ে দক্ষ এবং অবজেক্টটি ব্যবহারের পক্ষে সহজ হওয়ায় সাধারণত এসটিএল ধারকটিতে সরাসরি জিনিসগুলি সংরক্ষণ করা সবচেয়ে ভাল।

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


4
আপনার জিনিসগুলি বড় হলে এটি সর্বাধিক দক্ষ নয় এবং আপনি উপাদানগুলি ঘন ঘন ঘুরে দেখেন।
allyourcode

3

আপনার মনে হয় পার্থক্যটি ভালভাবে উপলব্ধি করতে পেরেছেন। যদি বস্তুগুলি ছোট এবং অনুলিপি করা সহজ হয় তবে তা যেকোন উপায়ে সেগুলি সংরক্ষণ করুন।

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

@ টরবজার্ন কাটা কাটা সম্পর্কে একটি ভাল ধারণা দেয়।


1
ওহ, এবং কখনও কখনও কখনও auto_ptr এর একটি সংগ্রহ তৈরি
Torbjörn Gyllebring

ঠিক আছে, অটো_পিটার একটি স্মার্ট পয়েন্টার নয় - এটি গণনা রেফার করে না।
লু ফ্রাঙ্কো

অটো_প্টারের কাছে অ-ধ্বংসাত্মক কপির শব্দার্থবিদ্যা নেই have থেকে একটি অটো_প্টার নিয়োগের কাজone দেওয়ারanother রেফারেন্সটি ছেড়ে দেয় oneএবং পরিবর্তন করবে one
অ্যান্ডি ফিংকেনস্ট্যাড্ট

3

পয়েন্টারগুলি ব্যবহার করা আরও কার্যকর হবে যেহেতু ধারকগুলি পুরো বস্তুর পরিবর্তে কেবলমাত্র পয়েন্টারগুলি অনুলিপি করবে।

এসটিএল পাত্রে এবং স্মার্ট পয়েন্টার সম্পর্কে এখানে কিছু দরকারী তথ্য রয়েছে:

স্ট্যান্ডার্ড পাত্রে স্ট্যান্ড :: অটো_পিটার <> ব্যবহার করা কেন ভুল?


2

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

অর্থাৎ,

std::vector<boost::shared_ptr<protocol> > protocols;
...
connection c(protocols[0].get()); // pointer to protocol stays valid even if resized

অন্য কেউ যদি বস্তুগুলির জন্য পয়েন্টার সঞ্চয় না করে বা তালিকাটি বৃদ্ধি এবং সঙ্কুচিত না হয় তবে কেবল সরল-পুরাতন অবজেক্ট হিসাবে সংরক্ষণ করুন:

std::vector<protocol> protocols;
connection c(protocols[0]); // value-semantics, takes a copy of the protocol

1

এই প্রশ্নটি আমাকে কিছুক্ষণের জন্য বগল করছে।

আমি পয়েন্টারগুলি সঞ্চয় করার দিকে ঝুঁকছি, তবে আমার কিছু অতিরিক্ত প্রয়োজনীয়তা রয়েছে (এসডিজিআইজি লুয়া র‌্যাপারস) যা আপনার ক্ষেত্রে প্রযোজ্য নাও হতে পারে।

এই পোস্টের সবচেয়ে গুরুত্বপূর্ণ পয়েন্টটি এটি ব্যবহার করে নিজেই পরীক্ষা করা আপনার অবজেক্ট করে

৫ মিলিয়ন অবজেক্টের সংগ্রহের জন্য সদস্য ফাংশনকে কল করার গতি পরীক্ষা করতে আজ আমি এটি করেছি 500

Xdir এবং ydir (সমস্ত ভাসমান সদস্য ভেরিয়েবল) এর উপর ভিত্তি করে ফাংশনটি x এবং y আপডেট করে।

আমি উভয় ধরণের অবজেক্টকে ধরে রাখতে একটি std :: list ব্যবহার করেছি এবং আমি দেখতে পেলাম যে তালিকার মধ্যে অবজেক্টটি স্টোর করা পয়েন্টার ব্যবহারের চেয়ে সামান্য দ্রুত। অন্যদিকে, পারফরম্যান্সটি খুব কাছাকাছি ছিল, সুতরাং এটি কীভাবে আপনার অ্যাপ্লিকেশনটিতে ব্যবহৃত হবে তা নেমে আসে।

রেফারেন্সের জন্য, আমার হার্ডওয়্যার -O3 এর সাথে পয়েন্টারগুলি সম্পূর্ণ হতে 41 সেকেন্ড সময় নিয়েছিল এবং কাঁচা বস্তুগুলি সম্পূর্ণ হতে 30 সেকেন্ড সময় নিয়েছিল।

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