সি ++ এ ফাংশনগুলিতে কীভাবে বস্তুগুলি পাস করবেন?


249

আমি সি ++ প্রোগ্রামিংয়ে নতুন, তবে জাভাতে আমার অভিজ্ঞতা আছে। কীভাবে সি ++ এ ফাংশনগুলিতে জিনিসগুলি পাস করতে হবে সে সম্পর্কে আমার গাইডেন্স দরকার।

আমার কি পয়েন্টার, রেফারেন্স, বা অ-পয়েন্টার এবং অ-রেফারেন্স মানগুলি পাস করতে হবে? আমার মনে আছে জাভাতে এ জাতীয় কোনও সমস্যা নেই কারণ আমরা কেবলমাত্র ভেরিয়েবলটি পাস করি যা অবজেক্টের রেফারেন্স রাখে।

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


6
আপনি কোন বই থেকে সি ++ শিখছেন?

17
যে বই জোরালোভাবে সুপারিশ করা হয় না । স্ট্যান লিপম্যানের সি ++ প্রাইমারের জন্য যান।
প্রসূন সৌরভ

23
ঠিক আছে, আপনার সমস্যা আছে। শিল্ডটি মূলত সিআর * পি - কোনেইগ এন্ড এমও দ্বারা এক্সিলারেটেড সি ++ পান।

9
আমি আশ্চর্য হই যে কীভাবে কেউ বজরেন স্ট্রস্ট্রুপ দ্বারা সি ++ প্রোগ্রামিং ভাষার উল্লেখ করেননি। সিজন ++ এর স্রষ্টা হলেন বাজর্ন স্ট্রস্ট্রপ। সি ++ শিখতে সত্যিই একটি ভাল বই।
জর্জ

15
@ জর্জ: টিসি ++ পিএল নতুনদের জন্য নয়, তবে এটি সি ++ এর বাইবেল হিসাবে বিবেচিত হয় । xD
প্রসূন সৌরভ

উত্তর:


277

সি ++ 11 এর জন্য থাম্বের বিধি :

মান দ্বারা পাস , যখন ছাড়া

  1. আপনার কাছে অবজেক্টটির মালিকানা প্রয়োজন নেই এবং একটি সাধারণ উপনাম করবে যা আপনি রেফারেন্সের মাধ্যমে পাস করেনconst ,
  2. আপনাকে অবশ্যই অবজেক্টটিকে রূপান্তর করতে হবে, এক্ষেত্রে অ- constমূল্যবান রেফারেন্স দিয়ে পাস ব্যবহার করতে হবে ,
  3. আপনি প্রাপ্ত ক্লাসগুলির অবজেক্টগুলিকে বেস ক্লাস হিসাবে পাস করেন, সেক্ষেত্রে আপনাকে রেফারেন্স দিয়ে পাস করতে হবে । ( constরেফারেন্স দিয়ে পাস করতে হবে কিনা তা নির্ধারণ করতে পূর্ববর্তী বিধিগুলি ব্যবহার করুন ।)

পয়েন্টার দ্বারা পাস কার্যত কখনও পরামর্শ দেওয়া হয় না। Olderচ্ছিক পরামিতিগুলি সর্বোত্তম হিসাবে একটি std::optional( boost::optionalপুরানো স্টাড লিবের জন্য) প্রকাশ করা হয় এবং রেফারেন্সের সাহায্যে এলিয়াসিং করা হয়।

সি ++ 11 এর সরানো শব্দার্থবিজ্ঞান জটিল বস্তুর জন্য এমনকি মান দ্বারা পাস এবং ফিরে আসা আরও অনেক আকর্ষণীয় করে তোলে।


সি ++ 03 এর জন্য থাম্বের বিধি :

রেফারেন্স দ্বারাconst যুক্তিগুলি পাস করুন , কখন ছাড়াই

  1. সেগুলি ফাংশনের অভ্যন্তরে পরিবর্তন করতে হবে এবং এই জাতীয় পরিবর্তনগুলি বাইরে প্রতিবিম্বিত হওয়া উচিত, সেক্ষেত্রে আপনি অ- constরেফারেন্সের মাধ্যমে পাস করেন
  2. ফাংশনটি কোনও যুক্তি ছাড়াই কলযোগ্য হওয়া উচিত, আপনি পয়েন্টার দিয়ে পাস করার ক্ষেত্রে ব্যবহারকারীরা NULL/ 0/ nullptrপরিবর্তে পাস করতে পারে ; যুক্তিটিতে আপনাকে কোনও পয়েন্টার দিয়ে যেতে হবে কিনা তা নির্ধারণ করতে পূর্ববর্তী নিয়মটি প্রয়োগ করুনconst
  3. এগুলি অন্তর্নির্মিত ধরণের, যা অনুলিপি দ্বারা পাস করা যেতে পারে
  4. সেগুলি ফাংশনের অভ্যন্তরে পরিবর্তন করতে হবে এবং এ জাতীয় পরিবর্তনগুলি বাইরে প্রতিবিম্বিত হওয়া উচিত নয় , সেই ক্ষেত্রে আপনি অনুলিপি দ্বারা পাস করতে পারেন (বিকল্পটি পূর্ববর্তী বিধি অনুসারে পাস এবং ফাংশনের অভ্যন্তরে একটি অনুলিপি তৈরি করা হবে)

(এখানে, "মান দ্বারা পাস" বলা হয় "অনুলিপি দ্বারা পাস", কারণ মান দ্বারা পাস করা সর্বদা সি ++ 03 এ একটি অনুলিপি তৈরি করে)


এর আরও অনেক কিছু রয়েছে তবে এই কয়েকটি শিক্ষানবিশের নিয়ম আপনাকে বেশ দূরে পেয়ে যাবে।


17
+1 - আমি আরও নোট করব যে কিছু (অর্থাত্ গুগল) মনে করে যে ফাংশনটির মধ্যে পরিবর্তিত হবে এমন অবজেক্টগুলি অ-কনস্ট্যান্ট রেফারেন্সের পরিবর্তে পয়েন্টারের মাধ্যমে পাস করা উচিত। যুক্তিটি হ'ল কোনও বস্তুর ঠিকানা যখন কোনও ফাংশনে প্রেরণ করা হয় তখন এটি আরও স্পষ্ট হয় যে বলেছিল যে ফাংশন এটি পরিবর্তন করতে পারে। উদাহরণ: রেফারেন্স সহ, কলটি ফু (বার); রেফারেন্সটি কনস্টেট কিনা বা না, পয়েন্টার সহ এটি ফু (& বার) হয়; এবং আরও স্পষ্ট যে foo একটি পরিবর্তনীয় বস্তু পাস করা হচ্ছে।
আরসি।

19
@ আরসি এখনও পয়েন্টারটি কনস্ট্যান্ট কিনা তা আপনাকে জানায় না। গুগলের নির্দেশিকা বিভিন্ন সি ++ অনলাইন সম্প্রদায়গুলিতে প্রচুর ঝাপটায় এসেছে - ন্যায়সঙ্গতভাবে, আইএমএইচও।

14
অন্য বিষয়গুলিতে গুগল হয়তো এগিয়ে চলেছে, সি ++ এ তাদের স্টাইল গাইড আসলে তেমন ভাল নয়।
ডেভিড রদ্রিগেজ - ড্রিবাস

4
@ অরুনসাহা: খাঁটি শৈলীর গাইড হিসাবে, স্ট্রোস্ট্রপের একটি গাইড রয়েছে যা একটি মহাকাশ সংস্থার জন্য তৈরি করা হয়েছিল। আমি গুগল গাইডের মাধ্যমে ব্রাউজ করেছি এবং বেশ কয়েকটি কারণে এটি পছন্দ করে নি। সুটার এবং আলেকজান্দ্রেস্কু সি ++ কোডিং স্ট্যান্ডার্ডগুলি পড়ার জন্য একটি দুর্দান্ত বই এবং আপনি বেশ কয়েকটি ভাল পরামর্শ পেতে পারেন তবে এটি আসলে কোনও স্টাইল গাইড নয় । আমি শৈলীর জন্য কোনও স্বয়ংক্রিয় পরীক্ষক , মানব এবং সাধারণ জ্ঞান ব্যতীত জানি না sense
ডেভিড রদ্রিগেজ - ড্রিবিস

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

107

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

রেফারেন্স দিয়ে পাস

রেফারেন্স দিয়ে পাস করার অর্থ হ'ল ফাংশনটি ধারণাগতভাবে আপনার অবজেক্ট উদাহরণটি গ্রহণ করবে এবং এর অনুলিপিটি নয়। রেফারেন্সটি ধারণামূলকভাবে কল করার প্রসঙ্গে ব্যবহৃত অবজেক্টটির একটি উপনাম এবং শূন্য হতে পারে না। ফাংশনের অভ্যন্তরে সঞ্চালিত সমস্ত ক্রিয়াকলাপগুলি ফাংশনের বাইরের অবজেক্টে প্রয়োগ হয়। এই সম্মেলনটি জাভা বা সি তে উপলব্ধ নয় is

মান দ্বারা পাস (এবং পাশ দিয়ে পয়েন্টার)

সংকলক কলিং প্রসঙ্গে বস্তুর একটি অনুলিপি তৈরি করবে এবং ফাংশনের ভিতরে সেই অনুলিপিটি ব্যবহার করবে। ফাংশনের অভ্যন্তরীণ সমস্ত ক্রিয়াকলাপগুলি বাহ্যিক উপাদান নয়, অনুলিপিতে সম্পন্ন হয়। এটি জাভাতে আদিম ধরণের জন্য সম্মেলন।

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

এটি সিতে ব্যবহৃত কনভেনশন হয় যখন কোনও ফাংশনটিতে বাহ্যিক চলক সংশোধন করা প্রয়োজন হয়, এবং জাভাতে রেফারেন্স প্রকারের সাথে ব্যবহৃত কনভেনশন: রেফারেন্সটি অনুলিপি করা হয় তবে রেফারেন্স করা বস্তুটি একই: রেফারেন্স / পয়েন্টারে পরিবর্তনগুলি বাইরে দৃশ্যমান হয় না ফাংশন, কিন্তু পয়েন্ট মেমরি পরিবর্তন হয়।

সমীকরণে কনস্টের যোগ করা

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

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

চলতি নিয়ম

এটি অনুসরণ করার জন্য কয়েকটি প্রাথমিক নিয়ম:

  • আদিম ধরণের জন্য পাস-বাই-মান পছন্দ করুন
  • অন্যান্য ধরণের ধ্রুবক রেফারেন্স সহ পাস বাই রেফারেন্স পছন্দ করুন
  • যদি ফাংশনটির আর্গুমেন্টটি সংশোধন করতে হয় তবে পাস-বাই-রেফারেন্সটি ব্যবহার করুন
  • যদি আর্গুমেন্টটি alচ্ছিক হয় তবে পাস-বাই-পয়েন্টার ব্যবহার করুন (constantচ্ছিক মানটি পরিবর্তিত করা উচিত না তবে স্থিরভাবে)

এই নিয়মগুলি থেকে অন্য ছোট বিচ্যুতি রয়েছে, যার মধ্যে প্রথমটি কোনও কোনও সামগ্রীর মালিকানা পরিচালনা করছে। যখন কোনও বস্তুটি গতিশীলভাবে নতুন দিয়ে বরাদ্দ করা হয়, তখন এটি মুছে ফেলা (বা [[] এর সংস্করণগুলি) দিয়ে অবশ্যই বিচ্ছিন্ন করতে হবে। যে অবজেক্ট বা ফাংশনটি অবজেক্টটির ধ্বংসের জন্য দায়ী তা সংস্থার মালিক হিসাবে বিবেচিত হয়। যখন কোডের একটি অংশে গতিশীলভাবে বরাদ্দকৃত অবজেক্ট তৈরি করা হয়, তবে মালিকানাটি অন্য কোনও উপাদানে স্থানান্তরিত হয় এটি সাধারণত পাস-বাই-পয়েন্টার শব্দার্থক দ্বারা সম্পন্ন করা হয়, বা স্মার্ট পয়েন্টার দিয়ে সম্ভব হলে।

সাইড নোট

সি ++ এবং জাভা রেফারেন্সের মধ্যে পার্থক্যের গুরুত্বকে গুরুত্ব দেওয়া জরুরী। সি ++ এ রেফারেন্সটি ধারণাগতভাবে অবজেক্টের উদাহরণ, এটির কোনও অ্যাক্সেসর নয়। সবচেয়ে সহজ উদাহরণটি হ'ল অদলবদল কার্যকারিতা:

// C++
class Type; // defined somewhere before, with the appropriate operations
void swap( Type & a, Type & b ) {
   Type tmp = a;
   a = b;
   b = tmp;
}
int main() {
   Type a, b;
   Type old_a = a, old_b = b;
   swap( a, b );
   assert( a == old_b );
   assert( b == old_a ); 
}

উপরের সোয়াপ ফাংশন উল্লেখগুলির ব্যবহারের মাধ্যমে এর উভয় যুক্তিই পরিবর্তন করে। জাভা এর নিকটতম কোড:

public class C {
   // ...
   public static void swap( C a, C b ) {
      C tmp = a;
      a = b;
      b = tmp;
   }
   public static void main( String args[] ) {
      C a = new C();
      C b = new C();
      C old_a = a;
      C old_b = b;
      swap( a, b ); 
      // a and b remain unchanged a==old_a, and b==old_b
   }
}

কোডের জাভা সংস্করণটি অভ্যন্তরীণভাবে রেফারেন্সগুলির অনুলিপিগুলিকে সংশোধন করবে, তবে প্রকৃত বস্তুগুলি বাহ্যিকভাবে পরিবর্তন করবে না। জাভা রেফারেন্সগুলি হ'ল সি পয়েন্টার ছাড়াই গাণিতিক গাণিতিক যা মান দ্বারা ফাংশনে রূপান্তরিত হয়।


4
@ ডেভিড-রদ্রিগেজ-ড্রিবিয়াস আমি থাম্ব বিভাগের নিয়ম পছন্দ করি, বিশেষত "আদিম ধরণের জন্য পাস-বাই-মান পছন্দ করুন"
ইয়াদাব

আমার মতে, এটি প্রশ্নের আরও ভাল উত্তর।
unrealsoul007

22

বিবেচনা করার জন্য বেশ কয়েকটি মামলা রয়েছে।

প্যারামিটার সংশোধিত ("আউট" এবং "ইন / আউট" পরামিতি)

void modifies(T &param);
// vs
void modifies(T *param);

এই কেসটি বেশিরভাগ শৈলীর বিষয়ে: আপনি কোডটি কল (আপত্তি) বা কল (& اعتراض) এর মতো দেখতে চান ? তবে, দুটি পয়েন্ট রয়েছে যেখানে পার্থক্যটি গুরুত্বপূর্ণ: নীচে theচ্ছিক ক্ষেত্রে এবং অপারেটরগুলি ওভারলোড করার সময় আপনি একটি রেফারেন্স ব্যবহার করতে চান।

... এবং alচ্ছিক

void modifies(T *param=0);  // default value optional, too
// vs
void modifies();
void modifies(T &param);

প্যারামিটারটি সংশোধিত হয়নি

void uses(T const &param);
// vs
void uses(T param);

এটি আকর্ষণীয় ঘটনা। থাম্বের নিয়ম হ'ল "অনুলিপি করতে সস্তা" প্রকারগুলি মান দ্বারা পাস হয় - এগুলি সাধারণত ছোট ধরণের (তবে সর্বদা নয়) - অন্যরা কনস্টের মাধ্যমে রেফার করে। যাইহোক, যদি আপনার নির্বিশেষে আপনার ফাংশনটির মধ্যে একটি অনুলিপি তৈরি করার প্রয়োজন হয় তবে আপনার মান দ্বারা পাস করা উচিত । (হ্যাঁ, এটি প্রয়োগের কিছুটা বিশদ প্রকাশ করে C সিস্ট লে সি ++। )

... এবং alচ্ছিক

void uses(T const *param=0);  // default value optional, too
// vs
void uses();
void uses(T const &param);  // or optional(T param)

এখানে সমস্ত পরিস্থিতির মধ্যে স্বল্পতম পার্থক্য রয়েছে, তাই আপনার জীবনকে সহজতর যে কোনওটি বেছে নিন।

মান অনুসারে একটি বাস্তবায়ন বিশদ Const

void f(T);
void f(T const);

এই ঘোষণাগুলি আসলে ঠিক একই কাজ! মান দ্বারা পাস করার সময়, কনস্ট খাঁটি একটি বাস্তবায়ন বিশদ। চেষ্টা কর:

void f(int);
void f(int const) { /* implements above function, not an overload */ }

typedef void NC(int);       // typedefing function types
typedef void C(int const);

NC *nc = &f;  // nc is a function pointer
C *c = nc;    // C and NC are identical types

3
+1 constমান দ্বারা পাস করার সময় আমি বাস্তবায়ন হওয়ার বিষয়ে জানতাম না ।
বালকি

20

মান দ্বারা পাস:

void func (vector v)

ফাংশনটি যখন পরিবেশ থেকে সম্পূর্ণ বিচ্ছিন্নতার প্রয়োজন হয় অর্থাৎ ফাংশনটি মূল ভেরিয়েবলটি পরিবর্তন করতে বাধা দেয় এবং ফাংশনটি সম্পাদনকালে অন্যান্য থ্রেডের মানটি পরিবর্তন করা থেকে বিরত রাখতে মান দ্বারা ভেরিয়েবলগুলি পাস করুন Pass

ডাউনসাইড হ'ল সিপিইউ চক্র এবং অবজেক্টটি অনুলিপি করতে ব্যয় করা অতিরিক্ত মেমরি।

কনস্ট্যান্ড রেফারেন্স দ্বারা পাস:

void func (const vector& v);

অনুলিপিটি অনুলিপি করার সময় এই ফর্মটি পাস-বাই-মান আচরণ অনুকরণ করে। ফাংশনটি আসল অবজেক্টে পঠিত অ্যাক্সেস পায় তবে এর মানটি পরিবর্তন করতে পারে না।

নেতিবাচক দিকটি থ্রেড সুরক্ষা: অন্য থ্রেড দ্বারা মূল অবজেক্টে করা যে কোনও পরিবর্তন ফাংশনের অভ্যন্তরে প্রদর্শিত হবে যখন এটি কার্যকর হচ্ছে।

নন-কনস্ট্যান্ট রেফারেন্স দিয়ে পাস করুন:

void func (vector& v)

এটি ব্যবহার করুন যখন ফাংশনটিতে ভেরিয়েবলের কিছু মান ফিরে লিখতে হয়, যা শেষ পর্যন্ত কলার দ্বারা ব্যবহৃত হয়।

কনস্টের রেফারেন্সের মতো এটি থ্রেড-নিরাপদ নয়।

কনস্ট পয়েন্টার দ্বারা পাস:

void func (const vector* vp);

কার্যত ভিন্ন ভিন্ন বাক্য গঠন ব্যতীত কনস্ট-রেফারেন্স দ্বারা পাসের সমান, একই সাথে কলিং ফাংশনটি NUL পয়েন্টারটি পাস করতে পারে তা প্রমাণ করার জন্য এটির কোনও বৈধ ডেটা নেই।

থ্রেড-নিরাপদ নয়।

নন-কনস্ট্যান্ট পয়েন্টার দিয়ে যান:

void func (vector* vp);

নন-কনস্ট্যান্ট রেফারেন্সের মতো। কলকারী সাধারণত NUL এ ভেরিয়েবল সেট করে যখন ফাংশনটি কোনও মান আবার না লেখার কথা বলে। এই কনভেনশনটি অনেক গুলিবিক এপিআইতে দেখা যায়। উদাহরণ:

void func (string* str, /* ... */) {
    if (str != NULL) {
        *str = some_value; // assign to *str only if it's non-null
    }
}

থ্রেড-নিরাপদ নয়, যেমন রেফারেন্স / পয়েন্টার দ্বারা সমস্ত পাসের মতো।


0

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

Class CPlusPlusJavaFunctionality {
    public:
       CPlusPlusJavaFunctionality(){
         attribute = new int;
         *attribute = value;
       }

       void setValue(int value){
           *attribute = value;
       }

       void getValue(){
          return *attribute;
       }

       ~ CPlusPlusJavaFuncitonality(){
          delete(attribute);
       }

    private:
       int *attribute;
}

void changeObjectAttribute(CPlusPlusJavaFunctionality obj, int value){
   int* prt = obj.attribute;
   *ptr = value;
}

int main(){

   CPlusPlusJavaFunctionality obj;

   obj.setValue(10);

   cout<< obj.getValue();  //output: 10

   changeObjectAttribute(obj, 15);

   cout<< obj.getValue();  //output: 15
}

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


-1

পরামিতি হিসাবে কোনও ফাংশনে কোনও বস্তুর পাস করার জন্য তিনটি পদ্ধতি রয়েছে:

  1. রেফারেন্স দ্বারা পাস
  2. মান দ্বারা পাস
  3. প্যারামিটারে ধ্রুবক যোগ করা হচ্ছে

নিম্নলিখিত উদাহরণটি দেখুন:

class Sample
{
public:
    int *ptr;
    int mVar;

    Sample(int i)
    {
        mVar = 4;
        ptr = new int(i);
    }

    ~Sample()
    {
        delete ptr;
    }

    void PrintVal()
    {
        cout << "The value of the pointer is " << *ptr << endl
             << "The value of the variable is " << mVar;
   }
};

void SomeFunc(Sample x)
{
cout << "Say i am in someFunc " << endl;
}


int main()
{

  Sample s1= 10;
  SomeFunc(s1);
  s1.PrintVal();
  char ch;
  cin >> ch;
}

আউটপুট:

বলুন আমি কিছুতে আছি
পয়েন্টারের
মান -17891602 হল ভেরিয়েবলের মান 4


এখানে কেবলমাত্র দুটি পদ্ধতি রয়েছে (প্রথম যেটি আপনি উল্লেখ করেছেন)। "প্যারামিটারে ধ্রুবক
এমএম

-1

সি ++ এ কাজ করার জন্য আর্গুমেন্ট / পরামিতিগুলি পাস করার উপায়গুলি নীচে।

1. মান দ্বারা।

// passing parameters by value . . .

void foo(int x) 
{
    x = 6;  
}

2. রেফারেন্স দ্বারা।

// passing parameters by reference . . .

void foo(const int &x) // x is a const reference
{
    x = 6;  
}

// passing parameters by const reference . . .

void foo(const int &x) // x is a const reference
{
    x = 6;  // compile error: a const reference cannot have its value changed!
}

3. বস্তু দ্বারা।

class abc
{
    display()
    {
        cout<<"Class abc";
    }
}


// pass object by value
void show(abc S)
{
    cout<<S.display();
}

// pass object by reference
void show(abc& S)
{
    cout<<S.display();
}

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