লিঙ্কযুক্ত তালিকাগুলি কেন নোডের অভ্যন্তরে নোড সঞ্চয় করার পরিবর্তে পয়েন্টার ব্যবহার করে


121

আমি জাভাতে আগে লিঙ্কযুক্ত তালিকার সাথে কাজ করেছি, তবে আমি সি ++ তে খুব নতুন very আমি এই নোড ক্লাসটি ব্যবহার করছিলাম যা আমাকে ঠিক একটি প্রকল্পে দেওয়া হয়েছিল

class Node
{
  public:
   Node(int data);

   int m_data;
   Node *m_next;
};

তবে আমার একটি প্রশ্ন ছিল যা খুব ভাল উত্তর দেওয়া হয়নি। কেন এটি ব্যবহার করা প্রয়োজন

Node *m_next;

পরিবর্তে তালিকার পরবর্তী নোডে নির্দেশ করুন

Node m_next;

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


14
আমাকে নিজে ক্ষমা করবেন? কেন এমন কোনও ভাষা নেই যেখানে সর্বদা পয়েন্টারটির কোনও লিঙ্কযুক্ত তালিকা নেই?
এঞ্জিউ আর

41
রেফারেন্স বনাম অবজেক্ট পয়েন্টারগুলির ক্ষেত্রে সি এবং সি ++ কীভাবে জাভা থেকে আলাদা তা লক্ষ করা গুরুত্বপূর্ণ। Node m_nextকোনও নোডের রেফারেন্স নয়, এটি সম্পূর্ণ Nodeনিজের জন্য সঞ্চয়স্থান ।
ব্রায়ান কেইন

41
@ নিজে জাভাতে পয়েন্টার রয়েছে আপনি কেবল এগুলি স্পষ্টভাবে ব্যবহার করবেন না।
এম0meni

27
কচ্ছপ সব পথ নিচে হয় না একটি বিকল্প। পাগলামি কোথাও শেষ হতে হবে।
WhozCraig

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

উত্তর:


218

এটি কেবল আরও ভাল নয়, এটি একমাত্র সম্ভাব্য উপায়।

আপনি যদি নিজের মধ্যে কোনও Node বস্তু সংরক্ষণ করেন তবে কী হবে sizeof(Node)? এটি হবে sizeof(int) + sizeof(Node), যা সমান হবে sizeof(int) + (sizeof(int) + sizeof(Node)), যা সমান হবে sizeof(int) + (sizeof(int) + (sizeof(int) + sizeof(Node))), ইত্যাদি অনন্ত।

এর মতো বস্তুর অস্তিত্ব থাকতে পারে না। এটা অসম্ভব


25
* যদি না এটি অলসভাবে মূল্যায়ন করা হয়। অসীম তালিকা সম্ভব, কেবল কঠোর মূল্যায়নের মাধ্যমে নয় with
কারসিজিনিট

55
@ কারসিজেনিকেট এটি নোড অবজেক্টের কোনও ফাংশনকে মূল্যায়ন / সম্পাদন করার বিষয়ে নয় - এটি নোডের প্রতিটি উদাহরণের মেমরি বিন্যাস সম্পর্কে, যা কোনও মূল্যায়ন হওয়ার আগে সংকলনের সময় নির্ধারণ করা উচিত।
পিটারিস

6
@ ডেভিডকে এটি করা যুক্তিসঙ্গতভাবে অসম্ভব। আপনি প্রয়োজন একটি পয়েন্টার (ভাল সত্যিই একটি অপ্রত্যক্ষ্যতার) এখানে - নিশ্চিত আপনি যে ভাষায় থেকে এটা লুকিয়ে রাখতে পারেন, কিন্তু শেষ পর্যন্ত, প্রায় কোন উপায়।
ভু

2
@ ডেভিড আমি বিভ্রান্ত প্রথমে আপনি সম্মত হন যে এটি যৌক্তিকভাবে অসম্ভব, তবে তারপরে আপনি কি তা নিয়ে চিন্তা করতে চান? সি বা সি ++ এর যে কোনও কিছুই সরিয়ে ফেলুন - আপনি যে কোনও ভাষাতে স্বপ্ন দেখতে পেলেন এমন কোনও ভাষাতেই এটি অসম্ভব যতটা আমি দেখতে পাচ্ছি। সেই কাঠামোটি সংজ্ঞা অনুসারে একটি অসীম পুনরাবৃত্তি এবং কিছু স্তর নির্দেশনা ছাড়া আমরা এটিকে ভাঙ্গতে পারি না।
ভু

13
@ বেঞ্জামিন আমি প্রকৃতপক্ষে উল্লেখ করেছি (কারণ আমি জানতাম যে অন্যথায় কেউ এটিকে নিয়ে আসবে - ভালভাবে সাহায্য করেনি) যে হাস্কেল সৃষ্টির সময় থাঙ্কগুলিকে বরাদ্দ করেছিল এবং তাই এটি কাজ করে কারণ এই থাঙ্করা আমাদের যে দিকনির্দেশনা দেয় তা দেয়। এটি ছদ্মবেশে অতিরিক্ত ডেটা যুক্ত পয়েন্টার ছাড়া আর কিছুই নয় ...
ভু

178

জাভাতে

Node m_node

অন্য নোডে পয়েন্টার সঞ্চয় করে। আপনার এটি সম্পর্কে কোনও পছন্দ নেই। সি ++ এ

Node *m_node

একই জিনিস মানে। পার্থক্যটি হ'ল সি ++ এ আপনি বস্তুটির পয়েন্টারের বিপরীতে সংরক্ষণ করতে পারেন। এজন্য আপনাকে বলতে হবে যে আপনি পয়েন্টার চান want সি ++ এ:

Node m_node

মানে এখানে নোডটি সরাসরি সঞ্চয় করুন (এবং এটি পরিষ্কারভাবে কোনও তালিকার পক্ষে কাজ করতে পারে না - আপনি পুনরাবৃত্তভাবে সংজ্ঞায়িত কাঠামো দিয়ে শেষ করেন)।


2
@ সালমানা আমি ইতিমধ্যে এটি জানতাম। আমি কেবল জানতে চেয়েছিলাম কেন এটি কোনও পয়েন্টার ছাড়া কাজ করবে না যা গ্রহণযোগ্য উত্তরটি আরও ভালভাবে ব্যাখ্যা করেছে।
m0meni

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

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

এটি কোনও আকার বা গতির সমস্যা নয় - এটি একটি অসম্ভব সমস্যা। অন্তর্ভুক্ত নোড অবজেক্টে নোড অবজেক্টের মধ্যে নোড অবজেক্ট অন্তর্ভুক্ত থাকবে ... আসলে এটি সংকলন করা অসম্ভব
pm100

3
@ পানজারক্রিসিস আমি জানি যে তারা উভয়েই একই ব্যাখ্যা দিচ্ছে। যদিও এই পদ্ধতির বিষয়টি আমার পক্ষে তেমন সহায়ক ছিল না কারণ এটি ইতিমধ্যে আমার কী বোঝার ছিল তার উপর দৃষ্টি নিবদ্ধ করেছিল: সি ++ তে পয়েন্টার কীভাবে কাজ করে এবং জাভাতে পয়েন্টার কীভাবে পরিচালনা করা হয়। গৃহীত উত্তরটি নির্দিষ্ট করে কেন পয়েন্টার ব্যবহার না করা অসম্ভব কারণ আকারটি গণনা করা যায় না। অন্যদিকে, এটিকে এটিকে "পুনরাবৃত্তভাবে সংজ্ঞায়িত কাঠামো" হিসাবে আরও অস্পষ্টভাবে ছেড়ে গেছে। আপনার সুনির্দিষ্ট লেখার PS টি এটি উভয়ের চেয়ে ভাল ব্যাখ্যা করেছে: ডি।
m0meni

38

সি ++ জাভা নয়। আপনি যখন লিখুন

Node m_next;

জাভাতে, লেখার মতোই

Node* m_next;

সি ++ এ। জাভাতে, পয়েন্টারটি অন্তর্নিহিত, সি ++ এ এটি সুস্পষ্ট। যদি লিখি

Node m_next;

সি ++ এ, আপনি Nodeযে বিষয়টিকে সংজ্ঞায়িত করছেন তার ভিতরে আপনি একটি উদাহরণ রেখেছেন । এটি সর্বদা থাকে এবং বাদ দেওয়া যায় না, এটি দিয়ে বরাদ্দ দেওয়া যায় না newএবং এটি সরানো যায় না। জাভাতে এই প্রভাবটি অর্জন করা অসম্ভব এবং জাভা একই বাক্য গঠনগুলির সাথে যা করেছে তা থেকে সম্পূর্ণ আলাদা।


1
জাভাতে অনুরূপ কিছু পাওয়ার জন্য সম্ভবত "প্রসারিত" হবে যদি সুপারনোড নোডকে প্রসারিত করে, সুপার নোডে নোডের সমস্ত বৈশিষ্ট্য অন্তর্ভুক্ত রয়েছে এবং সমস্ত অতিরিক্ত স্থান সংরক্ষণ করতে হবে। সুতরাং জাভাতে আপনি "নোড নোড বাড়ায়" করতে পারবেন না
ফ্যালকো

@ ফ্যালকো সত্য, উত্তরাধিকার বেস ক্লাসগুলিকে স্থানের অন্তর্ভুক্তির একটি রূপ। তবে, যেহেতু জাভা একাধিক উত্তরাধিকারের জন্য অনুমতি দেয় না (সি ++ এর বিপরীতে), আপনি উত্তরাধিকারের মাধ্যমে কেবলমাত্র অন্য একক পূর্ববর্তী শ্রেণীর উদাহরণ পেতে পারেন। এই কারণেই আমি উত্তরাধিকারটিকে স্থানের সদস্যদের অন্তর্ভুক্তির বিকল্প হিসাবে ভাবি না।
মাস্টার -

27

আপনি একটি পয়েন্টার ব্যবহার করুন, অন্যথায় আপনার কোড:

class Node
{
   //etc
   Node m_next; //non-pointer
};

… সংকলন করবে না , কারণ সংকলক আকারের গণনা করতে পারে না Node। এটি কারণ এটি নিজের উপর নির্ভর করে - যার অর্থ সংকলক এটি ঠিক করতে পারে না যে এটি কতটা স্মৃতি গ্রহণ করবে।


5
সবচেয়ে খারাপ, কোনও বৈধ আকারের উপস্থিতি নেই: যদি k == sizeof(Node)ধরে রাখে এবং আপনার ধরণের ডেটা থাকে, তবে এটিও sizeof(Node) = k + sizeof(Data) = sizeof(Node) + sizeof(Data)পরে রাখা উচিত sizeof(Node) > sizeof(Node)
বিটমাস্ক

4
@ বিটমাস্ক আসল সংখ্যায় কোনও বৈধ আকারের উপস্থিতি নেই । আপনি যদি ট্রান্সইনফাইনাইটগুলি অনুমতি দেন তবে aleph_0কাজ করে। (কেবল মাত্রাতিরিক্ত
পেডেন্টিক

2
@ কে_জি ওয়েল, সি / সি ++ স্ট্যান্ডার্ড ম্যান্ডেটস যে এর ফেরতের মান sizeofএকটি স্বাক্ষরবিহীন ইন্টিগ্রাল টাইপ, তাই স্থায়ী বা এমনকি বাস্তব আকারের আশা রয়েছে। (আরও বেশি পেডেন্টিক হচ্ছে!: পি)
টমাস

@ থমাস: কেউ কেউ এমনকি এখানে উল্লেখ করতে পারেন যে প্রাকৃতিক সংখ্যাগুলিও রয়েছে। : (পৃ -pedantic উপরের উপর যাচ্ছে)
বিট-মাস্কের

1
প্রকৃতপক্ষে, Nodeএই স্নিপেটের সমাপ্তির আগে এমনকি এটিও সংজ্ঞায়িত করা হয়নি, সুতরাং আপনি এটি ভিতরে ব্যবহার করতে পারবেন না। একজনকে এখনও অঘোষিত শ্রেণীর জন্য সুস্পষ্টভাবে ফরোয়ার্ড-ডিক্লেয়ারের অনুমতি দেওয়া হ'ল একটি সামান্য প্রতারণা যা ভাষার দ্বারা এই জাতীয় কাঠামোগুলি সম্ভব করার জন্য অনুমতিপ্রাপ্ত হয়, স্পষ্টভাবে পয়েন্টারগুলিকে সার্বক্ষণিক castালাই ছাড়াই।
osa

13

পরবর্তী ( Node m_next) নোড থাকতে হবে । এটি এটি নির্দেশ করবে না। এবং তখন উপাদানগুলির কোনও সংযোগ থাকবে না।


3
সবচেয়ে খারাপ, কোনও বস্তুর পক্ষে একই ধরণের কিছু থাকা যুক্তিযুক্তভাবে অসম্ভব।
মাইক সিমুর

এখনও কি প্রযুক্তিগতভাবে সংযোগ স্থাপন হবে না কারণ এটি নোড থাকবে এমন নোড যুক্ত কোনও নোড এবং তাই কি?
এম0meni

9
@ এআর:: না, সংশ্লেষের অর্থ এটি আক্ষরিক অর্থে অবজেক্টের অভ্যন্তরে, এর সাথে লিঙ্কযুক্ত নয়।
মাইক সিমুর

9

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

নীচে, আমি সি ++ এ আইটেমের তালিকা কীভাবে পরিচালনা করতে পারি তার চারটি পরিবর্তন বাস্তবায়িত করেছি।

  1. raw_pointer_demoআপনার মত একই পদ্ধতির ব্যবহার করে - কাঁচা পয়েন্টার ব্যবহারের সাথে ম্যানুয়াল মেমরি পরিচালনা প্রয়োজন। এখানে সি ++ ব্যবহার কেবল সিনট্যাকটিক-চিনির জন্য for , এবং ব্যবহৃত পদ্ধতির অন্যথায় সি ভাষার সাথে সামঞ্জস্যপূর্ণ।
  2. ইন shared_pointer_demoতালিকা ব্যবস্থাপনা এখনও ম্যানুয়ালি সম্পন্ন করা হয়, কিন্তু মেমরি ব্যবস্থাপনা হয় স্বয়ংক্রিয় (কাঁচা পয়েন্টার ব্যবহার করে না)। এটি সম্ভবত আপনি জাভা দিয়ে যা अनुभव করেছেন তার সাথে খুব মিল।
  3. std_list_demoস্ট্যান্ডার্ড-লাইব্রেরি listপাত্রে ব্যবহার করে । এটি যদি আপনি নিজের রোলিংয়ের পরিবর্তে বিদ্যমান লাইব্রেরিগুলিতে নির্ভর করেন তবে জিনিসগুলি কত সহজ হয় তা দেখায়।
  4. std_vector_demoস্ট্যান্ডার্ড-লাইব্রেরি vectorপাত্রে ব্যবহার করে । এটি একটি একক সঙ্গতিপূর্ণ মেমরি বরাদ্দে তালিকার সঞ্চয়স্থান পরিচালনা করে। অন্য কথায়, পৃথক উপাদানগুলিতে পয়েন্টার নেই। কিছু নির্দিষ্ট বরং চরম ক্ষেত্রে, এটি উল্লেখযোগ্যভাবে অদক্ষ হয়ে উঠতে পারে। সাধারণ ক্ষেত্রে, তবে এটি সি ++ এ তালিকা পরিচালনার জন্য প্রস্তাবিত সেরা অনুশীলন

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


/*BINFMTCXX: -Wall -Werror -std=c++11
*/

#include <iostream>
#include <algorithm>
#include <string>
#include <list>
#include <vector>
#include <memory>
using std::cerr;

/** Brief   Create a list, show it, then destroy it */
void raw_pointer_demo()
{
    cerr << "\n" << "raw_pointer_demo()..." << "\n";

    struct Node
    {
        Node(int data, Node *next) : data(data), next(next) {}
        int data;
        Node *next;
    };

    Node * items = 0;
    items = new Node(1,items);
    items = new Node(7,items);
    items = new Node(3,items);
    items = new Node(9,items);

    for (Node *i = items; i != 0; i = i->next)
        cerr << (i==items?"":", ") << i->data;
    cerr << "\n";

    // Erase the entire list
    while (items) {
        Node *temp = items;
        items = items->next;
        delete temp;
    }
}

raw_pointer_demo()...
9, 3, 7, 1

/** Brief   Create a list, show it, then destroy it */
void shared_pointer_demo()
{
    cerr << "\n" << "shared_pointer_demo()..." << "\n";

    struct Node; // Forward declaration of 'Node' required for typedef
    typedef std::shared_ptr<Node> Node_reference;

    struct Node
    {
        Node(int data, std::shared_ptr<Node> next ) : data(data), next(next) {}
        int data;
        Node_reference next;
    };

    Node_reference items = 0;
    items.reset( new Node(1,items) );
    items.reset( new Node(7,items) );
    items.reset( new Node(3,items) );
    items.reset( new Node(9,items) );

    for (Node_reference i = items; i != 0; i = i->next)
        cerr << (i==items?"":", ") << i->data;
    cerr<<"\n";

    // Erase the entire list
    while (items)
        items = items->next;
}

shared_pointer_demo()...
9, 3, 7, 1

/** Brief   Show the contents of a standard container */
template< typename C >
void show(std::string const & msg, C const & container)
{
    cerr << msg;
    bool first = true;
    for ( int i : container )
        cerr << (first?" ":", ") << i, first = false;
    cerr<<"\n";
}

/** Brief  Create a list, manipulate it, then destroy it */
void std_list_demo()
{
    cerr << "\n" << "std_list_demo()..." << "\n";

    // Initial list of integers
    std::list<int> items = { 9, 3, 7, 1 };
    show( "A: ", items );

    // Insert '8' before '3'
    items.insert(std::find( items.begin(), items.end(), 3), 8);
    show("B: ", items);

    // Sort the list
    items.sort();
    show( "C: ", items);

    // Erase '7'
    items.erase(std::find(items.begin(), items.end(), 7));
    show("D: ", items);

    // Erase the entire list
    items.clear();
    show("E: ", items);
}

std_list_demo()...
A:  9, 3, 7, 1
B:  9, 8, 3, 7, 1
C:  1, 3, 7, 8, 9
D:  1, 3, 8, 9
E:

/** brief  Create a list, manipulate it, then destroy it */
void std_vector_demo()
{
    cerr << "\n" << "std_vector_demo()..." << "\n";

    // Initial list of integers
    std::vector<int> items = { 9, 3, 7, 1 };
    show( "A: ", items );

    // Insert '8' before '3'
    items.insert(std::find(items.begin(), items.end(), 3), 8);
    show( "B: ", items );

    // Sort the list
    sort(items.begin(), items.end());
    show("C: ", items);

    // Erase '7'
    items.erase( std::find( items.begin(), items.end(), 7 ) );
    show("D: ", items);

    // Erase the entire list
    items.clear();
    show("E: ", items);
}

std_vector_demo()...
A:  9, 3, 7, 1
B:  9, 8, 3, 7, 1
C:  1, 3, 7, 8, 9
D:  1, 3, 8, 9
E:

int main()
{
    raw_pointer_demo();
    shared_pointer_demo();
    std_list_demo();
    std_vector_demo();
}

Node_referenceঘোষণা ঠিকানাগুলি উপরে জাভা এবং সি ++ মধ্যে সবচেয়ে আকর্ষণীয় ভাষা পর্যায়ের পার্থক্য করুন। জাভাতে, কোনও প্রকারের বস্তু ঘোষণার মাধ্যমে Nodeস্পষ্টতই একটি পৃথক বরাদ্দকৃত বস্তুর রেফারেন্স ব্যবহার করা হবে। সি ++ এ, আপনার কাছে রেফারেন্স (পয়েন্টার) বনাম সরাসরি (স্ট্যাক) বরাদ্দের পছন্দ রয়েছে - সুতরাং আপনাকে স্বতন্ত্রভাবে পার্থক্যটি পরিচালনা করতে হবে। বেশিরভাগ ক্ষেত্রে আপনি সরাসরি বরাদ্দ ব্যবহার করবেন, যদিও তালিকার উপাদানগুলির জন্য নয়।
ব্রেন্ট ব্র্যাডবার্ন

কেন আমি স্টাড :: ডিউক হওয়ার সম্ভাবনাটি সুপারিশ করিনি কেন জানি না ।
ব্রেন্ট ব্র্যাডবার্ন

8

সংক্ষিপ্ত বিবরণ

সি ++ তে অবজেক্টগুলিকে রেফারেন্স এবং বরাদ্দ দেওয়ার জন্য দুটি উপায় রয়েছে, যখন জাভাতে কেবল একটি উপায় আছে।

এটি ব্যাখ্যা করতে, নিম্নলিখিত চিত্রগুলি কীভাবে মেমরিতে বস্তুগুলি সংরক্ষণ করা হয় তা দেখান।

1.1 সি ++ পয়েন্টার ছাড়াই আইটেম

class AddressClass
{
  public:
    int      Code;
    char[50] Street;
    char[10] Number;
    char[50] POBox;
    char[50] City;
    char[50] State;
    char[50] Country;
};

class CustomerClass
{
  public:
    int          Code;
    char[50]     FirstName;
    char[50]     LastName;
    // "Address" IS NOT A pointer !!!
    AddressClass Address;
};

int main(...)
{
   CustomerClass MyCustomer();
     MyCustomer.Code = 1;
     strcpy(MyCustomer.FirstName, "John");
     strcpy(MyCustomer.LastName, "Doe");
     MyCustomer.Address.Code = 2;
     strcpy(MyCustomer.Address.Street, "Blue River");
     strcpy(MyCustomer.Address.Number, "2231 A");

   return 0;
} // int main (...)

.......................................
..+---------------------------------+..
..|          AddressClass           |..
..+---------------------------------+..
..| [+] int:      Code              |..
..| [+] char[50]: Street            |..
..| [+] char[10]: Number            |..
..| [+] char[50]: POBox             |..
..| [+] char[50]: City              |..
..| [+] char[50]: State             |..
..| [+] char[50]: Country           |..
..+---------------------------------+..
.......................................
..+---------------------------------+..
..|          CustomerClass          |..
..+---------------------------------+..
..| [+] int:      Code              |..
..| [+] char[50]: FirstName         |..
..| [+] char[50]: LastName          |..
..+---------------------------------+..
..| [+] AddressClass: Address       |..
..| +-----------------------------+ |..
..| | [+] int:      Code          | |..
..| | [+] char[50]: Street        | |..
..| | [+] char[10]: Number        | |..
..| | [+] char[50]: POBox         | |..
..| | [+] char[50]: City          | |..
..| | [+] char[50]: State         | |..
..| | [+] char[50]: Country       | |..
..| +-----------------------------+ |..
..+---------------------------------+..
.......................................

সতর্কতা : এই উদাহরণটিতে ব্যবহৃত সি ++ সিনট্যাক্স জাভাতে সিনট্যাক্সের মতো। তবে, মেমরির বরাদ্দ আলাদা।

১.২ সি ++ পয়েন্টার ব্যবহার করে আইটেম

class AddressClass
{
  public:
    int      Code;
    char[50] Street;
    char[10] Number;
    char[50] POBox;
    char[50] City;
    char[50] State;
    char[50] Country;
};

class CustomerClass
{
  public:
    int           Code;
    char[50]      FirstName;
    char[50]      LastName;
    // "Address" IS A pointer !!!
    AddressClass* Address;
};

.......................................
..+-----------------------------+......
..|        AddressClass         +<--+..
..+-----------------------------+...|..
..| [+] int:      Code          |...|..
..| [+] char[50]: Street        |...|..
..| [+] char[10]: Number        |...|..
..| [+] char[50]: POBox         |...|..
..| [+] char[50]: City          |...|..
..| [+] char[50]: State         |...|..
..| [+] char[50]: Country       |...|..
..+-----------------------------+...|..
....................................|..
..+-----------------------------+...|..
..|         CustomerClass       |...|..
..+-----------------------------+...|..
..| [+] int:      Code          |...|..
..| [+] char[50]: FirstName     |...|..
..| [+] char[50]: LastName      |...|..
..| [+] AddressClass*: Address  +---+..
..+-----------------------------+......
.......................................

int main(...)
{
   CustomerClass* MyCustomer = new CustomerClass();
     MyCustomer->Code = 1;
     strcpy(MyCustomer->FirstName, "John");
     strcpy(MyCustomer->LastName, "Doe");

     AddressClass* MyCustomer->Address = new AddressClass();
     MyCustomer->Address->Code = 2;
     strcpy(MyCustomer->Address->Street, "Blue River");
     strcpy(MyCustomer->Address->Number, "2231 A");

     free MyCustomer->Address();
     free MyCustomer();

   return 0;
} // int main (...)

আপনি যদি উভয় পদ্ধতির মধ্যে পার্থক্যটি পরীক্ষা করেন তবে আপনি দেখতে পাবেন যে প্রথম কৌশলটিতে ঠিকানা আইটেমটি গ্রাহকের মধ্যে বরাদ্দ করা হয়, অন্যদিকে, আপনাকে প্রতিটি ঠিকানা স্পষ্টভাবে তৈরি করতে হবে।

সতর্কতা: জাভা এই দ্বিতীয় কৌশলটির মতো মেমরির মধ্যে অবজেক্টগুলি বরাদ্দ করে তবে সিনট্যাক্সটি প্রথম পদ্ধতির মতো যা নতুনদের "সি ++" এর জন্য বিভ্রান্ত করতে পারে।

বাস্তবায়ন

সুতরাং আপনার তালিকার উদাহরণ নীচের উদাহরণের মতো কিছু হতে পারে।

class Node
{
  public:
   Node(int data);

   int m_data;
   Node *m_next;
};

.......................................
..+-----------------------------+......
..|            Node             |......
..+-----------------------------+......
..| [+] int:           m_data   |......
..| [+] Node*:         m_next   +---+..
..+-----------------------------+...|..
....................................|..
..+-----------------------------+...|..
..|            Node             +<--+..
..+-----------------------------+......
..| [+] int:           m_data   |......
..| [+] Node*:         m_next   +---+..
..+-----------------------------+...|..
....................................|..
..+-----------------------------+...|..
..|            Node             +<--+..
..+-----------------------------+......
..| [+] int:           m_data   |......
..| [+] Node*:         m_next   +---+..
..+-----------------------------+...|..
....................................v..
...................................[X].
.......................................

সারসংক্ষেপ

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

হালনাগাদ:

@ হ্যাকগুলি তার পোস্টে মন্তব্য করেছে বলে উল্লেখযোগ্য worth

যে কখনও কখনও, রেফারেন্স বা অবজেক্ট পয়েন্টার, নেস্টেড আইটেমগুলি নির্দেশ করে (ওরফে "ইউএমএল রচনা")।

এবং কখনও কখনও, রেফারেন্স বা অবজেক্ট পয়েন্টারগুলি বাহ্যিক আইটেমগুলি নির্দেশ করে (ওরফে "ইউএমএল সমষ্টি")।

কিন্তু, একই শ্রেণীর নেস্টেড আইটেমগুলি, "নো-পয়েন্টার" কৌশল দিয়ে প্রয়োগ করা যাবে না।


7

সাইড নোটে, কোনও শ্রেণি বা কাঠামোর প্রথম সদস্য যদি পরবর্তী পয়েন্টার হয় (সুতরাং কোনও ভার্চুয়াল ফাংশন বা শ্রেণীর কোনও বৈশিষ্ট্য যার অর্থ পরবর্তী কোনও শ্রেণি বা কাঠামোর প্রথম সদস্য নয়) তবে আপনি ঠিক পরবর্তী পয়েন্টার সহ একটি "বেস" শ্রেণি বা কাঠামো ব্যবহার করতে পারে এবং বেসিক লিঙ্কযুক্ত তালিকার জন্য সাধারণ কোড ব্যবহার করতে পারে যেমন অ্যাপেন্ড, পূর্বে সন্নিবেশ করা, সামনে থেকে পুনরুদ্ধার করা, ...। এটি কারণ সি / সি ++ গ্যারান্টি দেয় যে কোনও শ্রেণি বা কাঠামোর প্রথম সদস্যের ঠিকানা শ্রেণি বা কাঠামোর ঠিকানা হিসাবে একই। বেস নোড শ্রেণি বা স্ট্রাক্টের কেবলমাত্র বেসিক লিঙ্কযুক্ত তালিকার ফাংশনগুলির দ্বারা ব্যবহৃত পরবর্তী পয়েন্টার থাকবে, তবে বেস নোড টাইপ এবং "প্রাপ্ত" নোডের মধ্যে রূপান্তর করার জন্য টাইপকাস্টিং প্রয়োজন হবে। পার্শ্ব নোট - সি ++ এ, যদি বেস নোড শ্রেণিতে কেবল একটি পরবর্তী পয়েন্টার থাকে,


6

লিঙ্কযুক্ত তালিকায় পয়েন্টার ব্যবহার করা ভাল কেন?

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

Node m_nodeপরিবর্তে যদি ব্যবহৃত হয় তবে সংকলকটির আকার সম্পর্কে কোনও ধারণা নেই Nodeএবং এটি গণনার এক অসীম পুনরাবৃত্তিতে আটকে থাকবে sizeof(Node)। সর্বদা মনে রাখবেন: একটি শ্রেণিতে তার নিজস্ব ধরণের সদস্য থাকতে পারে না


5

কারণ এটি সি ++ এ

int main (..)
{
    MyClass myObject;

    // or

    MyClass * myObjectPointer = new MyClass();

    ..
}

জাভা এই সমতুল্য

public static void main (..)
{
    MyClass myObjectReference = new MyClass();
}

যেখানে উভয়ই MyClassডিফল্ট কনস্ট্রাক্টর ব্যবহার করে একটি নতুন অবজেক্ট তৈরি করে।


0

লিঙ্কযুক্ত তালিকাগুলি কেন নোডের অভ্যন্তরে নোডগুলি সঞ্চয় করার পরিবর্তে পয়েন্টার ব্যবহার করে?

অবশ্যই একটি তুচ্ছ উত্তর আছে।

তারা না করে থাকেন তাহলে প্রতি সংযোগ আছে একটি পয়েন্টার পরবর্তী এক নোড, তারা হবে না লিঙ্ক তালিকা

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

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