সি ++ কনস্টেট ব্যবহারের ব্যাখ্যা


99
const int* const Method3(const int* const&) const;

কেউ কি প্রতিটি কনস্টের ব্যবহার ব্যাখ্যা করতে পারেন?


27
জটিল ঘোষণাগুলি বোঝার জন্য আমি এই পদ্ধতিটি সত্যিই পছন্দ করি: c-faq.com/decl/spiral.anderson.html
জেসন

উত্তর:


77

এটি পড়ুন: https://isocpp.org/wiki/faq/const-cor درستness

চূড়ান্ত constঅর্থ হল যে ফাংশনটি Method3তার শ্রেণীর অ-পরিবর্তনীয় সদস্যদের সংশোধন করে না।

const int* constএকটি ধ্রুবক int এর জন্য একটি ধ্রুবক পয়েন্টার অর্থ: অর্থাত্ একটি পয়েন্টার যা পরিবর্তন করা যায় না, এমন কোনও অন্তর্কে যা পরিবর্তন করা যায় না: const int&এটির মধ্যে পার্থক্য কেবলমাত্র এটিই হতে পারেnull

const int* const&একটি ধ্রুবক int এর একটি ধ্রুবক পয়েন্টারটির উল্লেখ সাধারণত পয়েন্টারগুলি রেফারেন্স দ্বারা পাস হয় না; const int* &আরও বোধগম্য করে কারণ এর অর্থ const int* const&হ'ল পদ্ধতি কল চলাকালীন পয়েন্টারটি পরিবর্তিত হতে পারে, যা কেবলমাত্র রেফারেন্স দ্বারা পয়েন্টারটি পাস করার জন্য আমি দেখতে পাচ্ছি, সমস্ত অভিপ্রায় এবং উদ্দেশ্যে একই কারণ const int* constএটি সম্ভবত কম দক্ষ যেমন পয়েন্টারগুলি সরল পুরাতন ডেটা (পিওডি) ধরণের হয় এবং এগুলি সাধারণত মান দ্বারা পাস করা উচিত।


104

এটি সম্পূর্ণ সমতুল্য হিসাবে পুনরায় লিখলে এটি বোঝা সহজ

// v───v───v───v───v───v───v───v───v───v───v───v─┬┐
//                                               ││
//  v──#1    v─#2             v──#3    v─#4      #5
   int const * const Method3(int const * const&) const;

তারপরে এটি ডান থেকে বামে পড়ুন।

# 5 বলছে যে পুরো ফাংশন ডিক্লেয়ারটি বামে const, যা বোঝায় যে এটি একটি ফাংশন পরিবর্তে অগত্যা সদস্য ফাংশন।

# 4 বলছে যে বাম দিকে পয়েন্টারটি const(অন্য কোনও ঠিকানার দিকে নির্দেশিত হতে পারে না)।

# 3 বলছে যে intবাম দিকের অংশটি হ'ল const(আলাদা মান হিসাবে পরিবর্তন করা যাবে না)।

# 2 বলছে যে বাম দিকে পয়েন্টার const

# 1 বলছে যে intবামদিকে আছে const

সব কিছু একসাথে রেখে, আপনি এটি constসদস্য ফাংশন হিসাবে পড়তে পারেন Method3যা কোনও constপয়েন্টারের রেফারেন্স নেয় int const(বা ক const int, যদি আপনি চান) এবং constএকটি int const( const int) তে একটি পয়েন্টার ফেরত দেয় ।

(এনবি # 2 সম্পূর্ণরূপে অতিরিক্ত প্রয়োজন হয় ))


22

সবার আগে const Tসমান T const

const int* constসুতরাং সমতুল্য int const * const

constএগুলিতে প্রচুর টোকেন এবং পয়েন্টার সহ অভিব্যক্তি পড়ার সময় , সর্বদা এগুলি ডান থেকে বামে (উপরে রূপান্তরটি প্রয়োগ করার পরে) পড়ার চেষ্টা করুন । সুতরাং এক্ষেত্রে রিটার্ন মান হ'ল একটি কনস্টের প্রতিবন্ধকint । পয়েন্টার নিজেই তৈরি করা constএখানে কোনও অর্থবোধ করে না যেহেতু রিটার্ন মান কোনও লভ্যালু নয় যা পরিবর্তিত হতে পারে। পয়েন্টটি তৈরি করা constতবে গ্যারান্টি দেয় যে কলার ফিরে আসা int(বা এর অ্যারে int) সংশোধন করতে পারে না Method3

const int*const&হয়ে যায় int const*const&, সুতরাং এটি কোনও কনস্টের কাছে কনস্ট পয়েন্টারের রেফারেন্সint । রেফারেন্সগুলি দিয়ে পুরুষদের কোনও বোধগম্যতা দিয়ে কোনও কনস্ট পয়েন্টার পাস করা - আপনি উল্লেখযোগ্য মানটি সংশোধন করতে পারবেন না কারণ পয়েন্টারটি হ'ল constএবং রেফারেন্স এবং পয়েন্টারগুলি সমান স্টোরেজ দখল করে রাখে যাতে কোনও স্থানের সঞ্চয়ও হয় না।

শেষটি constনির্দেশ করে যে পদ্ধতিটি thisবস্তুটি সংশোধন করে না । thisপদ্ধতি শরীরের মধ্যে পয়েন্টার (তাত্ত্বিক) ঘোষণা থাকবে T const * const this। এর অর্থ একটি const T*অবজেক্ট কল করতে সক্ষম হবে T::Method3()


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

12

নিয়মগুলি মনে রাখার একটি সহজ উপায় constহ'ল এটি এইভাবে চিন্তা করা: constএটির বাম দিকের জিনিসটির জন্য প্রযোজ্য, যদি না তার বামে কিছুই না থাকে।

সুতরাং এর ক্ষেত্রে const int * const, প্রথম কনস্টের বামে কিছুই নেই, তাই এটি প্রযোজ্য intএবং দ্বিতীয়টির বামে কিছু আছে, তাই এটি পয়েন্টারের ক্ষেত্রে প্রযোজ্য।

এই নিয়মটি আপনাকে জানায় যে আপনার যেখানে আছে সেখানে কী ঘটবে const int const *। যেহেতু উভয় কনস্টের প্রয়োগই intএই অভিব্যক্তিটিতে প্রযোজনীয় এবং তাই অবৈধ।


3
const /* don't modify the int or array of ints' value(s) */
int* const /* as a retval, ignored. useless declaration */
Method3(const /* don't modify the int or array of ints' value(s) */
int* const /* don't modify the pointer's value, the address to which `pointer` points to. e.g. you cannot say `++pointer` */
&) const; /* this method does not modify the instance/object which implements the method */

3

আমি "ঘড়ি" বা "সর্পিল" পদ্ধতিটি ব্যবহার করতে চাই যেখানে শনাক্তকারী নাম থেকে শুরু হয় (এই ক্ষেত্রে Method3) আপনি ডিকোড করার জন্য বাম থেকে ডানদিক থেকে বামে ইত্যাদি পিছনে পিছনে পড়ে থাকেন etc. নামকরণ অনুষ্ঠান. সুতরাং const int* const Method3(const int* const&) constএমন একটি শ্রেণিবদ্ধ পদ্ধতি যা কোনও শ্রেণীর সদস্যকে পরিবর্তন করে না (কিছু নামবিহীন শ্রেণীর) এবং একটি পয়েন্টারের কাছে ধ্রুবক রেফারেন্স নেয় যা একটি ধ্রুবককে নির্দেশ করে intএবং একটি ধ্রুবককে একটি স্থির পয়েন্টার দেয়int

আশাকরি এটা সাহায্য করবে,

জেসন


2

সি ++ এ কনস্টেন্টকে মনে রাখার একটি সহজ উপায় হ'ল যখন আপনি কোনও কোডটি ফর্মটিতে দেখেন যেমন:

XXX const;
const YYY;

এক্সএক্সএক্স, ওয়াইওয়াই একটি ধ্রুবক উপাদান,
XXX constফর্ম হবে:

function ( def var ) const;    ------#1
* const;                       ------#2

const YYY ফর্ম:

const int;                     ------#3
const double;

লোকেরা সাধারণত এই ধরণের ব্যবহার করে। আপনি "const&"কোথাও দেখলে , বিভ্রান্ত বোধ করবেন না, কনস্ট নিজের আগে কিছু বর্ণনা করছে। সুতরাং এই সমস্যার উত্তর এখন স্ব-স্পষ্ট।

const int* const Method3(const int* const&) const;
  |          |             |          |       |
  #3         #2            #3         #2      #1

2

আমি কেবল const int* const&এটিই উল্লেখ করতে চাই যে এটি অবশ্যই একটি ধ্রুবক রেফারেন্স const int*। উদাহরণ স্বরূপ:

int i = 0;
int j = 1;
int* p = &i;
int* q = &j;
const int* const& cpref = p;
cpref = q; //Error: assignment of read-only reference 'cpref'

এটি এর ক্ষেত্রেও int* const&, যার অর্থ: "একটি ধ্রুবক উল্লেখ int*"।
তবে const int*&এটি একটি অ-ধ্রুবক রেফারেন্স const int*
আশাকরি এটা সাহায্য করবে.


1

ডান থেকে বামে পড়া মডিফায়ারগুলি বোঝা আরও সহজ করে তোলে।

একটি কনস্ট পদ্ধতি যা কনস্ট কনটকে কনস্ট পয়েন্টারের রেফারেন্স নেয় Method3যা একটি কনট কনটকে কনস্ট পয়েন্টার ফেরত দেয়।

  1. একটি কনস্টের পদ্ধতি সদস্যদের সংশোধন করতে পারে না (যদি না তারা স্পষ্টতই হয় mutable)
  2. একটি কনস্ট পয়েন্টার অন্য কিছুতে নির্দেশ করতে পরিবর্তন করা যায় না
  3. একটি কনট ইনট (বা অন্য কোনও ধরণের) সংশোধন করা যায় না

1

কনস্ট # 1: মেথড 3 দ্বারা ফিরে আসা পয়েন্টারটি কোনও কনট ইন্টিকে বোঝায়।

কনস্ট # 2: ফাংশন দ্বারা ফিরিয়ে দেওয়া পয়েন্টার মানটি, নিজেই, কনস্টের হয়। এটি একটি অকেজো কনস্ট (যদিও গ্রামীণিকভাবে বৈধ), কারণ কোনও ফাংশন থেকে ফেরতের মান একটি এল-মান হতে পারে না।

কনস্ট # 3: পয়েন্টার প্রকারটি কনস্ট্যান্টের সাথে ফাংশন পয়েন্টের রেফারেন্স দিয়ে পাস করেছে।

কনস্ট # 4: ফাংশনটির রেফারেন্স দ্বারা প্রদত্ত পয়েন্টার মানটি নিজেই একটি কনস্ট পয়েন্টার। কনস্ট্যান্ট হিসাবে কোনও ফাংশনে পাস হওয়া কোনও মানটি সাধারণত অর্থহীন হতে পারে তবে এই মানটি রেফারেন্স দ্বারা পাস করা হয়, সুতরাং এটি অর্থবোধক হতে পারে।

কনস্ট # 5: ফাংশন (সম্ভবত একটি সদস্য ফাংশন) কনস্ট, যার অর্থ এটি (ক) কোন অংশের অবজেক্টের কোনও সদস্যকে নতুন মান নির্ধারণের অনুমতি দেয় না বা (খ) অবিচ্ছিন্ন সদস্য ফাংশন কল করে বস্তু বা এর সদস্যদের যেকোন ক্ষেত্রে


0
  • const পদ্ধতির শেষে কোয়ালিফায়ার হ'ল নির্দেশক বস্তুর স্থিতি পরিবর্তন করা যাচ্ছে না।

  • const int*const&রেফারেন্স দ্বারা কনস্ট স্থানে একটি কনস্ট পয়েন্টার প্রাপ্তি নির্দেশ করে। এটি ভিন্ন স্থানের দিকে নির্দেশ করতে পরিবর্তিত হতে পারে না বা যে দিকে নির্দেশ করছে তার মানও পরিবর্তন করতে পারে না।

  • const int*const প্রত্যাবর্তন মান যা স্থির অবস্থানের জন্য একটি ধ্রুবক পয়েন্টারও।


0

কয়েকটি ধারণা এই ধারণাটি প্রদর্শন করতে ভাল হতে পারে, ততই ভাল ইমো।

class TestClass
{
private:
   int iValue;
   int* oValuePtr;
   int& oValueRef;

public:
   int TestClass::ByValMethod1(int Value)
   {
      // Value can be modified
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   int TestClass::ByValMethod2(const int Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   const int TestClass::ByValMethod3(int Value)
   {
      // Value can be modified
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   const int TestClass::ByValMethod4(const int Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // iValue can be modified
      iValue = Value;
      iValue += 1;

      // Return value can be modified
      return ++iValue;
   }

   const int TestClass::ByValMethod5(const int Value) const
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // iValue *cannot* be modified
      // Access through a const object
      iValue = Value;
      iValue += 1;

      // Return value *cannot* be modified
      // Access through a const object
      return ++iValue;
   }

   int& TestClass::ByRefMethod1(int& Value)
   {
      // Value can be modified
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   int& TestClass::ByRefMethod2(const int& Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   const int& TestClass::ByRefMethod3(int& Value)
   {
      // Value can be modified
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   const int& TestClass::ByRefMethod4(const int& Value)
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   const int& TestClass::ByRefMethod5(const int& Value) const
   {
      // Value *cannot* be modified
      // Variable is const variable
      Value++;

      // oValueRef can be modified
      oValueRef = Value;
      oValueRef += 1;

      // Return value can be modified
      return ++oValueRef;
   }

   int* TestClass::PointerMethod1(int* Value)
   {
      // Value can be modified
      Value++;

      // oValuePtr can be assigned
      oValuePtr = Value;

      // oValuePtr can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   int* TestClass::PointerMethod2(const int* Value)
   {
      // Value can be modified
      Value++;

      // oValuePtr cannot be assigned
      // const int* to int*
      oValuePtr = Value;

      // oValuePtr can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   const int* TestClass::PointerMethod3(int* Value)
   {
      // Value can be modified
      Value++;

      // oValuePtr can be assigned
      oValuePtr = Value;

      // iValue can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   const int* TestClass::PointerMethod4(const int* Value)
   {
      // Value cannot be modified
      Value++;

      // oValuePtr *cannot* be assigned
      // const int* to int*
      oValuePtr = Value;

      // oValuePtr can be modified
      oValuePtr += 1;

      // Return value can be modified
      return ++oValuePtr;
   }

   const int* TestClass::PointerMethod5(const int* Value) const
   {
      // Value can be modified
      ++Value;

      // oValuePtr *cannot* be assigned
      // const int* to int* const
      // Access through a const object
      oValuePtr = Value;

      // oValuePtr *cannot* be modified
      // Access through a const object
      oValuePtr += 1;

      // Return value *cannot* be modified
      return ++oValuePtr;
   }
};

আশা করি এটা কাজে লাগবে!

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