ফাংশন পরামিতিগুলির জন্য 'কনস্ট' ব্যবহার করুন


396

আপনি কতদূর যেতে চান const? আপনি constযখন প্রয়োজন তখন কেবল ফাংশনগুলি তৈরি করেন বা আপনি পুরো হোগে গিয়ে সর্বত্র ব্যবহার করেন? উদাহরণস্বরূপ, একটি সাধারণ মিউটরটি কল্পনা করুন যা একক বুলিয়ান প্যারামিটার নেয়:

void SetValue(const bool b) { my_val_ = b; }

এটি কি constআসলেই কার্যকর? ব্যক্তিগতভাবে আমি প্যারামিটারগুলি সহ এটি ব্যাপকভাবে ব্যবহার করতে পছন্দ করি, তবে এই ক্ষেত্রে আমি ভাবছি যে এটি সার্থক কিনা?

আমি এটি জানতে পেরে অবাক হয়েছি যে আপনি constকোনও ফাংশন ঘোষণায় পরামিতিগুলি বাদ দিতে পারেন তবে এটি ফাংশন সংজ্ঞাতে অন্তর্ভুক্ত করতে পারেন, যেমন:

.h ফাইল

void func(int n, long l);

.cpp ফাইল

void func(const int n, const long l)

এরজন্য কি কোন কারণ আছে? এটা আমার কাছে কিছুটা অস্বাভাবিক মনে হচ্ছে।


আমি একমত নই .H ফাইলে অবশ্যই কনস্ট সংজ্ঞা থাকতে হবে। যদি তা না হয় তবে কনস্ট্রাক্ট প্যারামিটারগুলি যদি ফাংশনে প্রেরণ করা হয় তবে সংকলক একটি ত্রুটি উত্পন্ন করবে, কারণ .h ফাইলের প্রোটোটাইপটিতে কনস্ট সংজ্ঞা নেই।
সেলভিয়ান

10
আমি রাজী. :-) (এই প্রশ্নটি দিয়ে, শেষ মন্তব্যটি নয়!) যদি ফাংশনের শরীরে কোনও মান পরিবর্তন করা না যায় তবে এটি নির্বোধ == বা = বাগগুলি থামাতে সহায়তা করতে পারে, আপনার কখনও উভয়কেই সংঘাত দেওয়া উচিত নয়, (যদি এটি মান দ্বারা পাস হয়েছে, আপনি অন্যথায় অবশ্যই) যদিও এটি সম্পর্কে তর্ক করা যথেষ্ট গুরুতর নয়!
ক্রিস হুয়াং-লিভার 14

19
@ সেলউইন: এমনকি আপনি যদি কোনও অনুষ্ঠানের কাছে কোনও সংঘাত পাস করেন, যদিও এটি অনুলিপি করা হচ্ছে (যেহেতু এটি কোনও রেফারেন্স নয়), এবং তাই কনস্ট-নেস কোনও বিষয় নয়।
জাল্ফ

1
এই প্রশ্নে একই বিতর্ক ঘটছে: স্ট্যাকওভারফ্লো
আংশিক

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

উত্তর:


187

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

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


57
আমি 'খারাপ স্টাইল' অংশের সাথে একমত হতে পারি না। ড্রপ constফাংশন এগুলির নমুনা থেকে সুবিধা হলো আপনি হেডার ফাইল পরিবর্তন করতে যদি আপনি ড্রপ করার সিদ্ধান্ত নেন প্রয়োজন হবে না হয়েছে constপরে বাস্তবায়ন অংশ থেকে।
মিশা গার্নি

4
"আমি ব্যক্তিগতভাবে রেফারেন্স এবং পয়েন্টার প্যারামিটার ব্যতীত কনস্ট ব্যবহার করতে চাই না" " হতে পারে আপনার স্পষ্ট করে দেওয়া উচিত যে "আমি ফাংশন ঘোষণায় অতিরিক্ত অতিরিক্ত কোয়ালিফায়ার ব্যবহার করার প্রবণতা রাখি না, তবে constযেখানে এটি একটি কার্যকর তাত্পর্য তৈরি করে সেখানে ব্যবহার করুন ।"
উত্সাহকটি

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

4
int getDouble(int a){ ++a; return 2*a; }এটা চেষ্টা কর. অবশ্যই, ++aসেখানে কিছুই করার আছে কিন্তু এটা করতে সময় একটি দীর্ঘ সময়কাল ধরে একাধিক প্রোগ্রামার দ্বারা লিখিত একটি দীর্ঘ ফাংশন সেখানে পাওয়া যাবে। আমি দৃ strongly়ভাবে লিখতে পরামর্শ int getDouble( const int a ){ //... }দেব যা সন্ধানের সময় একটি সংকলন ত্রুটি তৈরি করবে ++a;
dom_beau

3
কার তথ্য কোনটির প্রয়োজন তা সমস্ত বিষয়। আপনি মান দ্বারা পরামিতি সরবরাহ করেন যাতে কলারের সাথে এটি কী করা হয় তা (অভ্যন্তরীণভাবে) আপনাকে কিছু জানার দরকার নেই । সুতরাং class Foo { int multiply(int a, int b) const; }আপনার শিরোনামে লিখুন । আপনার বাস্তবায়নের ক্ষেত্রে আপনি যত্ন নিচ্ছেন যে আপনি কোনও পরিবর্তন না করার প্রতিশ্রুতি দিতে পারেন aএবং bতাই int Foo::multiply(const int a, const int b) const { }এখানে বোঝা যায়। (সিডিনোট: কলার এবং বাস্তবায়ন উভয়ই এই বিষয়টি সম্পর্কে যত্নশীল যে ফাংশনটি তার Fooবস্তুর কোনও পরিবর্তন করে না , এভাবে এটি তার ঘোষণার শেষে
কনস্ট

415

"তর্কটি অর্থহীন হয় যখন আর্গুমেন্টটি মান দ্বারা পাস করা হয় যেহেতু আপনি কলারের অবজেক্টটি পরিবর্তন করবেন না।"

ভুল।

এটি আপনার কোড এবং আপনার অনুমানগুলি স্ব-ডকুমেন্টিং সম্পর্কে।

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

এছাড়াও, যেমনটি আগে কেউ উল্লেখ করেছেন, এটি সংকলকটিকে কিছুটা অপ্টিমাইজ করতে সহায়তা করতে পারে (যদিও এটি দীর্ঘ শট)।


41
সম্পূর্ণ একমত. এটি মানুষের সাথে যোগাযোগের এবং ভেরিয়েবলের সাথে কী করা উচিত তা সীমাবদ্ধ করার বিষয়ে।
লেন হলগেট

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

26
আমি এটিকে ভোট দিয়েছি পরামিতিটি 'কনস্ট' ঘোষণা করা প্যারামিটারে অর্থপূর্ণ তথ্য যুক্ত করে। তারা কোডটির মূল লেখক কী উদ্দেশ্য নিয়েছিল তা হাইলাইট করে এবং সময়ের সাথে সাথে কোডটির রক্ষণাবেক্ষণে সহায়তা করবে।
রিচার্ড কর্ডেন

13
@ টায়ালো: আপনি ভুল বুঝবেন। এটি কোডের একটি ব্লকের ভিতরে স্থানীয় পরিবর্তনশীলকে কনস্ট হিসাবে চিহ্নিত করার বিষয়ে (এটি কোনও ফাংশন হতে পারে)। আমি কোনও স্থানীয় ভেরিয়েবলের জন্যও একই কাজ করব। কনস্ট-সঠিক, এমন একটি এপিআই থাকা অর্থোন্নাল যা সত্যই গুরুত্বপূর্ণ।
rlerallut

56
এবং এটি ফাংশনের অভ্যন্তরে বাগগুলি ধরতে পারে - আপনি যদি জানেন যে কোনও প্যারামিটারটি পরিবর্তন করা উচিত নয়, তবে এটির ঘোষণা দেওয়ার অর্থ সংকলক আপনাকে বলবে যে আপনি দুর্ঘটনাক্রমে এটি সংশোধন করেছেন কিনা।
অ্যাড্রিয়ান

156

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

আহ, আমি ভেরিয়েবল ছিল ইচ্ছুক const ডিফল্টরূপে এবং চপল অ const ভেরিয়েবল জন্য প্রয়োজন ছিল :)


4
"আমি চাই ভেরিয়েবলগুলি ডিফল্টরূপে কনস্ট হয়" - একটি অক্সিমোরন ?? 8-) সিরিয়াসলি, কীভাবে "কনস্টেটিং" সমস্ত কিছু আপনাকে কোডটি আনুভূমিক কোডে সহায়তা করে? যদি মূল লেখক একটি অনুমিত ধ্রুবক যুক্তি পরিবর্তন করে, আপনি কীভাবে জানবেন যে ভার ধ্রুবক হওয়ার কথা ছিল? তদ্ব্যতীত, (অ-যুক্তিযুক্ত) ভেরিয়েবলগুলির বৃহত সংখ্যাটি হ'ল ... পরিবর্তনশীল। সুতরাং আপনি প্রক্রিয়াটি শুরু করার পরে খুব শীঘ্রই সংকলকটি ভেঙে যেতে হবে, না?
ysap

8
@ এসএপ, ১. যতটা সম্ভব কনস্টোনাল চিহ্নিতকরণ আমাকে দেখতে দেয় যে কোন অংশগুলি চলছে এবং কোনটি নয়। আমার অভিজ্ঞতায়, অনেক স্থানীয় লোকই অন্য উপায়ে নয়, বাস্তব উপস্থাপক। ২. "কনস্ট ভেরিয়েবল" / "অপরিবর্তনীয় ভেরিয়েবল" শব্দটি অক্সিমোরন হিসাবে শোনাতে পারে তবে এটি কার্যকরী ভাষায় স্ট্যান্ডার্ড অনুশীলন, পাশাপাশি কিছু অ-কার্যকরী; উদাহরণস্বরূপ মরিচা দেখুন: doc.rust-lang.org/book/variable-bindings.html
কনস্টান্টিন

1
সি ++ তেও এখন কিছু পরিস্থিতিতে স্ট্যান্ডার্ড; উদাহরণস্বরূপ, ল্যাম্বডা [x](){return ++x;}একটি ত্রুটি; দেখতে এখানে
anatolyg

10
ভেরিয়েবল " const" ডিফল্টরূপে মরচে :)
ফিনিক্স

চলকগুলি পরিবর্তিত হওয়ার অনুমতি দেওয়ার জন্য অ্যাসাইনিয়েবলের প্রয়োজন হয় না; তারা যে মূল্য দিয়ে আরম্ভ করা হয় তা রানটাইম এও পরিবর্তিত হতে পারে।
স্ফিংক্স

80

নিম্নলিখিত দুটি লাইন কার্যত সমতুল্য:

int foo (int a);
int foo (const int a);

স্পষ্টতই আপনি যদি এটি দ্বিতীয় উপায়ে সংজ্ঞায়িত করেন তবে aআপনি তার শরীরে কোনও পরিবর্তন করতে পারবেন না fooতবে বাইরে থেকে কোনও পার্থক্য নেই।

constরেফারেন্স বা পয়েন্টার প্যারামিটার সহ সত্যই যেখানে কাজ আসে:

int foo (const BigStruct &a);
int foo (const BigStruct *a);

এটি যা বলে তা হ'ল foo একটি বৃহত প্যারামিটার নিতে পারে, সম্ভবত কোনও ডেটা স্ট্রাকচার যা গিগাবাইট আকারের, এটি অনুলিপি না করে। এছাড়াও, এটি কলকারীকে বলে, "ফুও * সেই প্যারামিটারের সামগ্রী পরিবর্তন করবে না change" কনস্ট্যান্ড রেফারেন্স পাস করা সংকলককে কিছু কার্যকারিতা সংক্রান্ত সিদ্ধান্ত গ্রহণের অনুমতি দেয়।

*: যদি না এটি কনস্ট-নেসটি দূরে সরিয়ে দেয় তবে এটি অন্য পোস্ট।


3
এই প্রশ্নটি এটাই নয়; অবশ্যই রেফারেন্সড বা পয়েন্ট-টু আর্গুমেন্টের জন্য কনস্ট ব্যবহার করা ভাল ধারণা (যদি রেফারেন্সযুক্ত বা পয়েন্ট-টু মান সংশোধন না করা হয়)। মনে রাখবেন যে এটি আপনার পয়েন্টার উদাহরণের মধ্যে পরামিতি নয় ; এটি পরামিতি যে জিনিস পয়েন্ট।
টিএমএল

> একটি কনস্ট্যান্ড রেফারেন্স পাস করাও সংকলককে কিছু কার্যকারিতা সংক্রান্ত সিদ্ধান্ত নিতে মঞ্জুরি দেয়। ক্লাসিক্যাল ভ্রান্তি -
সংকলকটি নিজের জন্য

73

অতিরিক্ত এফফ্লিয়াস কনস্টের কোনও এপিআই স্ট্যান্ড পয়েন্ট থেকে খারাপ:

কলার বা এপিআই ব্যবহারকারীর কাছে কোনও অর্থবহ প্রতিশ্রুতি না দেওয়ার সময় আপনার এপিআইতে মান ব্যঙ্গ করে এমন আন্তঃজনিত ধরণের পরামিতিগুলির জন্য আপনার কোডগুলিতে অতিরিক্ত অতিরিক্ত ত্রুটিযুক্ত কনস্টের স্থাপন করা (এটি কেবলমাত্র প্রয়োগকে বাধা দেয়)।

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

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

সুতরাং আসুন আমরা যেভাবেই পারি কনটেড করার চেষ্টা করি:

void mungerum(char * buffer, const char * mask, int count);

void mungerum(char * const buffer, const char * const mask, const int count);

উপরের কোড লাইন বিবেচনা করুন। ঘোষণাপত্রটি কেবল আরও বিশৃঙ্খল এবং দীর্ঘতর এবং পড়া আরও কঠিন নয় তবে চারটি 'কনস্ট' কীওয়ার্ডের মধ্যে তিনটি এপিআই ব্যবহারকারী নিরাপদে উপেক্ষা করতে পারে। তবে 'কনস্ট' অতিরিক্ত ব্যবহারের ফলে দ্বিতীয় লাইনটি সম্ভাব্য ঝুঁকিপূর্ণ হয়ে উঠেছে !

কেন?

প্রথম প্যারামিটারের একটি দ্রুত ভুল পড়া char * const bufferআপনাকে মনে করতে পারে যে এটি ডেটা বাফারে যে মেমোরিটিকে পাস করেছে তা মেমরিটি পরিবর্তন করবে না - তবে, এটি সত্য নয়! অনাবৃত 'কনস্ট' আপনার এপিআই সম্পর্কে বিপজ্জনক এবং ভুল অনুমানের দিকে পরিচালিত করতে পারে যখন স্ক্যান করা হয় বা দ্রুত অপ্রচারিত হয়।


অতিরিক্ত প্রয়োগকারী কোনও কোড বাস্তবায়ন স্ট্যান্ড-পয়েন্ট থেকে খারাপ are

#if FLEXIBLE_IMPLEMENTATION
       #define SUPERFLUOUS_CONST
#else
       #define SUPERFLUOUS_CONST             const
#endif

void bytecopy(char * SUPERFLUOUS_CONST dest,
   const char *source, SUPERFLUOUS_CONST int count);

যদি FLEXIBLE_IMPLEMENTATION সত্য না হয়, তবে নীচের প্রথম উপায়ে ফাংশনটি প্রয়োগ না করার জন্য এপিআই "প্রতিশ্রুতিবদ্ধ" is

void bytecopy(char * SUPERFLUOUS_CONST dest,
   const char *source, SUPERFLUOUS_CONST int count)
{
       // Will break if !FLEXIBLE_IMPLEMENTATION
       while(count--)
       {
              *dest++=*source++;
       }
}

void bytecopy(char * SUPERFLUOUS_CONST dest,
   const char *source, SUPERFLUOUS_CONST int count)
{
       for(int i=0;i<count;i++)
       {
              dest[i]=source[i];
       }
}

এটি করার একটি খুব নির্বোধ প্রতিশ্রুতি। আপনার এমন একজনকে কেন এমন প্রতিশ্রুতি দেওয়া উচিত যা আপনার কলারে কোনও লাভ দেয় না এবং কেবল আপনার বাস্তবায়ন সীমাবদ্ধ করে?

এগুলি উভয়ই একই ফাংশনের কার্যকর বৈধ বাস্তবায়ন যদিও আপনি যা করেছেন তা সবই আপনার পিঠের পিছনে একটি হাত বেঁধে দেওয়া হয়েছে।

তদ্ব্যতীত, এটি খুব অগভীর প্রতিশ্রুতি যা সহজেই (এবং আইনত উদ্বেগিত হয়)।

inline void bytecopyWrapped(char * dest,
   const char *source, int count)
{
       while(count--)
       {
              *dest++=*source++;
       }
}
void bytecopy(char * SUPERFLUOUS_CONST dest,
   const char *source,SUPERFLUOUS_CONST int count)
{
    bytecopyWrapped(dest, source, count);
}

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

এই অতিমাত্রায় কনস্টের মুভি বাজে লোকের প্রতিশ্রুতি ছাড়া আর মূল্য নেই।


তবে মিথ্যা বলার ক্ষমতা আরও খারাপ হয়:

আমি আলোকিত হয়েছি যে আপনি জালিয়াতি কনস্ট ব্যবহার করে শিরোনাম (ঘোষণাপত্র) এবং কোড (সংজ্ঞা) এ কনস্টেট মিল করতে পারেন। কনস্ট-হ্যাপি অ্যাডভোকেটরা দাবী করেন যে এটি একটি ভাল জিনিস কারণ এটি আপনাকে কেবল সংজ্ঞাটিতে রাখতে দেয়।

// Example of const only in definition, not declaration
class foo { void test(int *pi); };
void foo::test(int * const pi) { }

তবে, কথোপকথনটি সত্য ... আপনি কেবলমাত্র ঘোষণায় একটি স্পুরিয়াস কনস্ট রাখতে পারেন এবং সংজ্ঞাতে এটিকে উপেক্ষা করতে পারেন। এটি কেবলমাত্র একটি এপিআইতে অতিমাত্রায় কনস্টকে আরও ভয়ঙ্কর জিনিস এবং একটি ভয়াবহ মিথ্যা করে তোলে - উদাহরণটি দেখুন:

class foo
{
    void test(int * const pi);
};

void foo::test(int *pi) // Look, the const in the definition is so superfluous I can ignore it here
{
    pi++;  // I promised in my definition I wouldn't modify this
}

সমস্ত অপ্রয়োজনীয় কনস্ট আসলে বাস্তবে পরিবর্তনকারীকে পরিবর্তন করতে বা নন-কনস্ট্যান্ট রেফারেন্সের মাধ্যমে ভেরিয়েবলটি পাস করতে চাইলে তাকে অন্য স্থানীয় অনুলিপি বা একটি র‌্যাপার ফাংশন ব্যবহার করতে বাধ্য করে প্রয়োগকারীর কোডটি কম পঠনযোগ্য করে তোলে।

এই উদাহরণটি দেখুন। কোনটি বেশি পঠনযোগ্য? এটি কি স্পষ্ট যে দ্বিতীয় ফাংশনে অতিরিক্ত পরিবর্তনশীল হওয়ার একমাত্র কারণ হ'ল কিছু এপিআই ডিজাইনার একটি অতিমাত্রায় কনস্টে ফেলেছিলেন?

struct llist
{
    llist * next;
};

void walkllist(llist *plist)
{
    llist *pnext;
    while(plist)
    {
        pnext=plist->next;
        walk(plist);
        plist=pnext;    // This line wouldn't compile if plist was const
    }
}

void walkllist(llist * SUPERFLUOUS_CONST plist)
{
    llist * pnotconst=plist;
    llist *pnext;
    while(pnotconst)
    {
        pnext=pnotconst->next;
        walk(pnotconst);
        pnotconst=pnext;
    }
}

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


9
ডাউনভোটস কেন? আপনি যদি ডাউনটাতে একটি সংক্ষিপ্ত মন্তব্য রেখে যান তবে এটি আরও বেশি সহায়ক।
অ্যাডিসাক

7
কনস্ট আর্গুমেন্ট ব্যবহারের পুরো বিন্দুটি চিহ্নিত লাইনটিকে ব্যর্থ করে দেওয়া (plist = pnext)। ফাংশন যুক্তি অপরিবর্তনীয় রাখা এটি একটি যুক্তিসঙ্গত সুরক্ষা ব্যবস্থা। আমি আপনার বক্তব্যের সাথে একমত নই যে এগুলি ফাংশন ঘোষণার ক্ষেত্রে খারাপ (যেহেতু তারা অতিশয় উজ্জীবিত) তবে তারা বাস্তবায়ন ব্লকে তাদের উদ্দেশ্যগুলি পরিবেশন করতে পারে।
Touko

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

17
@ jw013 সঠিক, void foo(int)এবং void foo(const int)ঠিক একই ফাংশন, ওভারলোড নয়। ideone.com/npN4W4 আদর্শone.com/tZav9R এখানে কনস্টটি শুধুমাত্র ফাংশন বডিটির একটি বাস্তবায়ন বিশদ, এবং ওভারলোড রেজোলিউশনে কোনও প্রভাব ফেলেনি। নিরাপদ ও সুন্দর এপিআই এর জন্য ঘোষণাপত্রের বাইরে রেখে দিন , তবে আপনি অনুলিপি করা মানটি পরিবর্তন না করার ইচ্ছাটিতে থাকলে সংজ্ঞাটিকে স্থির রাখুন
Oktalist

3
@ অ্যাডিসাক আমি জানি এটি পুরানো, তবে আমি বিশ্বাস করি যে পাবলিক এপিআইয়ের সঠিক ব্যবহারটি অন্য উপায়ে হবে। এই ভাবে ইন্টার্নালগুলিতে কাজ করা বিকাশকারীরা pi++যখন ভুল করার কথা না হয় তেমনি ভুল করেন না।
কফিঅ্যান্ডকোড

39

কনস্টের সি ++ এ ডিফল্ট হওয়া উচিত ছিল। এটার মত :

int i = 5 ; // i is a constant

var int i = 5 ; // i is a real variable

8
ঠিক আমার চিন্তা।
কনস্টান্টিন

24
সি এর সাথে সামঞ্জস্যতা খুব গুরুত্বপূর্ণ, কমপক্ষে এমন লোকদের জন্য যা সি ++ ডিজাইন করে, এমনকি এটি বিবেচনা করতে।

4
মজার বিষয়, আমি এটি কখনই ভাবিনি।
ড্যান

6
একইভাবে, unsignedসি ++ এ ডিফল্ট হওয়া উচিত ছিল। এটি পছন্দ: int i = 5; // i is unsignedএবং signed int i = 5; // i is signed
hkBattousai

25

আমি যখন জীবিতের জন্য সি ++ কোড করে থাকি তখন আমি যা করতে পারি তার সবই নষ্ট করে দিয়েছিলাম। সংকলকটি আপনাকে সহায়তা করার জন্য কনস্ট ব্যবহার করা দুর্দান্ত উপায়। উদাহরণস্বরূপ, আপনার পদ্ধতির রিটার্ন মানগুলিকে সংযুক্তকরণ আপনাকে টাইপস থেকে রক্ষা করতে পারে যেমন:

foo() = 42

যখন আপনি বোঝাতে চেয়েছিলেন:

foo() == 42

যদি foo () নির্ধারণ করা হয় তবে অ-নিরপেক্ষ রেফারেন্সটি ফেরত দিতে হবে:

int& foo() { /* ... */ }

সংকলকটি আনন্দের সাথে আপনাকে ফাংশন কল দিয়ে ফিরে আসা বেনাম অস্থায়ীটির জন্য একটি মান নির্ধারণ করতে দেবে। এটি কনস্ট্যান্ট করা:

const int& foo() { /* ... */ }

এই সম্ভাবনা দূর করে।


6
কোন সংকলকটি দিয়ে সে কাজ করেছিল? সংকলনের চেষ্টা করার সময় জিসিসি একটি ত্রুটি দেয় foo() = 42: ত্রুটি: অ্যাসাইনমেন্টের বাম অপারেন্ড হিসাবে লভ্যালু প্রয়োজন
gavrie

এটি ঠিক ভুল। foo () = 42 2 2 3 এর সমান, যেমন একটি সংকলক ত্রুটি। এবং কোন কনস্টকে ফিরিয়ে দেওয়া সম্পূর্ণ অর্থহীন। এটি বিল্ট-ইন টাইপের জন্য কিছু করে না।
জোশ

2
আমি কনস্টের এই ব্যবহারটির মুখোমুখি হয়েছি এবং আমি আপনাকে বলতে পারি, শেষ পর্যন্ত এটি সুবিধার চেয়ে আরও বেশি ঝামেলা সৃষ্টি করে। ইঙ্গিত: এর const int foo()চেয়ে আলাদা ধরণের int foo(), যা আপনি ফাংশন পয়েন্টার, সিগন্যাল / স্লট সিস্টেম বা বুস্ট :: বাইন্ডের মতো জিনিসগুলি ব্যবহার করা হলে আপনাকে বড় সমস্যার মধ্যে নিয়ে আসে।
মাফানে

2
রেফারেন্স রিটার্ন মান অন্তর্ভুক্ত করার জন্য আমি কোড সংশোধন করেছি।
অ্যাভিডি

রিটার্ন ভ্যালু অপ্টিমাইজেশনের কারণে const int& foo()কার্যকরভাবে একই রকম হয় না int foo()?
জানটিয়ার

15

সেখানে comp.lang.c নিবন্ধ ++,। সংযত পুরানো 'উইক গুরু "এ এই বিষয়ে একটি ভাল আলোচনা এখানে

সংশ্লিষ্ট GOTW নিবন্ধ ঔষধি Sutter এর ওয়েব সাইটে পাওয়া যায় এখানে


1
ভেষজ সুটার একটি সত্যিই স্মার্ট লোক :-) অবশ্যই পড়ার পক্ষে মূল্যবান এবং আমি তার সমস্ত বিষয়গুলির সাথে একমত হই।
আদিসাক

2
ভাল ভাল নিবন্ধ কিন্তু আমি যুক্তি সম্পর্কে তার সাথে একমত নই। আমি তাদের পাশাপাশি স্থির করে রাখি কারণ এগুলি ভেরিয়েবলের মতো এবং আমি চাই না যে কেউ আমার যুক্তিতে কোনও পরিবর্তন আনুক।
কিউবিজিজেড

9

আমি বলছি আপনার মান পরামিতি কনস্ট।

এই বগি ফাংশনটি বিবেচনা করুন:

bool isZero(int number)
{
  if (number = 0)  // whoops, should be number == 0
    return true;
  else
    return false;
}

যদি নম্বর প্যারামিটারটি কনস্টেন্ট হয় তবে সংকলকটি থামিয়ে আমাদের বাগের বিষয়ে সতর্ক করবে।


2
(0 == সংখ্যা) যদি অন্য উপায় ব্যবহার করে ... অন্যথায় ...;
জোহানেস স্কাউব -

5
: @ ChrisHuang-Leaver ভয়ঙ্কর না যায়, তা Yoda মত কথা বলা যদি তুমি করো stackoverflow.com/a/2430307/210916
MPelletier

জিসিসি / কলং -ওয়াল আপনাকে -স্বীকৃতি দেয়, যা আপনাকে "যদি ((সংখ্যা = 0))" তৈরি করার দাবি করে তবে যদি এটি সত্যই আপনি করতে চান। যা Yoda হওয়ার বিকল্প হিসাবে ভাল কাজ করে।
জেটস্কি এস-টাইপ

8

আমি ফাংশন পরামিতিগুলিতে কনস্ট ব্যবহার করি যা রেফারেন্স (বা পয়েন্টার) যা কেবলমাত্র [ইন] ডেটা এবং ফাংশনটির মাধ্যমে সংশোধিত হবে না। অর্থ, যখন কোনও রেফারেন্স ব্যবহারের উদ্দেশ্য হ'ল ডেটা অনুলিপি করা এড়ানো এবং পাস হওয়া প্যারামিটারটি পরিবর্তন না করা।

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

জন্য ফাংশন স্বাক্ষর

void foo(int a);

এবং

void foo(const int a);

একই। যা আপনার .c এবং .h ব্যাখ্যা করে

আসফ


6

আপনি ব্যবহার করেন তাহলে ->*বা .*অপারেটর, এটি একটি আবশ্যক।

এটি আপনাকে এমন কিছু লেখা থেকে বাধা দেয়

void foo(Bar *p) { if (++p->*member > 0) { ... } }

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

আমি যা বলতে চেয়েছিলাম তা ছিল

void foo(Bar *p) { if (++(p->*member) > 0) { ... } }

এবং যদি আমি একটি করা ছিল constমধ্যবর্তী Bar *এবং p, কম্পাইলার আমাকে বলতাম।


4
আমি অবিলম্বে অপারেটরের অগ্রাধিকার সম্পর্কে একটি রেফারেন্স যাচাই করব যখন আমি অনেক অপারেটর (যদি আমি ইতিমধ্যে 100% না জানি) একত্রে মিশ্রিত হব, সুতরাং আইএমও এটি একটি নন-ইস্যু।
এম কে 12

5

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


5

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

রেফারেন্স দিয়ে পাস করার সময় কনস্টকে অগ্রাধিকার দেওয়া উচিত, যদি না ফাংশনের উদ্দেশ্যটি পাস করা মানটি পরিবর্তন করে।

অবশেষে, একটি ফাংশন যা বর্তমান অবজেক্ট (এটি) পরিবর্তন করতে পারে না এবং সম্ভবত কনস্ট হিসাবে ঘোষণা করা উচিত। একটি উদাহরণ নীচে:

int SomeClass::GetValue() const {return m_internalValue;}

এটি এই প্রতিশ্রুতি যা এই কলটি প্রয়োগ করা হয়েছে সেই অবজেক্টটি সংশোধন করবেন না। অন্য কথায়, আপনি কল করতে পারেন:

const SomeClass* pSomeClass;
pSomeClass->GetValue();

যদি ফাংশনটি কনস্টেন্ট না হয় তবে এটি একটি সংকলক সতর্কবার্তা তৈরি করবে।


5

মান পরামিতি 'কনস্ট' চিহ্নিত করা অবশ্যই একটি বিষয়গত জিনিস।

তবে আমি প্রকৃতপক্ষে আপনার উদাহরণের মতো মান পরামিতিগুলি চিহ্নিত করতে পছন্দ করি।

void func(const int n, const long l) { /* ... */ }

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

একটি সংক্ষিপ্ত ফাংশনের জন্য, সেখানে 'কনস্ট' রাখার পক্ষে এটি যুক্তিযুক্তভাবে সময় / জায়গার অপচয়, কারণ এটি প্রায়শই স্পষ্ট যে আর্গুমেন্টগুলি ফাংশনটির মাধ্যমে সংশোধিত হয় না।

তবে বৃহত্তর ফাংশনের জন্য এটি প্রয়োগের ডকুমেন্টেশনের একটি ফর্ম এবং এটি সংকলক দ্বারা প্রয়োগ করা হয়।

আমি নিশ্চিত হতে পারি যে আমি 'এন' এবং 'এল' দিয়ে কিছু গণনা করি কিনা, আমি আলাদা ফলাফল পাওয়ার আশঙ্কা ছাড়াই সেই গণনাটি রিফ্যাক্টর / সরিয়ে নিতে পারি কারণ আমি এমন একটি জায়গা মিস করেছি যেখানে একটি বা উভয়ই পরিবর্তিত হয়েছে।

যেহেতু এটি বাস্তবায়নের বিশদ, তাই আপনাকে শিরোনামে মান প্যারামিটারগুলি ঘোষণা করার দরকার নেই, যেমন প্রয়োগকরণ যেমন ব্যবহার করে তেমনি একই নামের সাথে ফাংশন পরামিতিগুলি আপনাকে প্রকাশ করার দরকার নেই।


4

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


3

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

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

সি ++ এর কনস্ট-নির্ভুলতার ধারণা সহ কিছু অতিরিক্ত লাগেজ রয়েছে, তাই এটি আরও বেশি গুরুত্বপূর্ণ হয়ে ওঠে।


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

3

1. আমার মূল্যায়নের ভিত্তিতে সেরা উত্তর:

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

২. আমার নিজের কথা (সেরা উত্তরের সাথে একমত):

  1. পাস-বাই-ভ্যালুর জন্য যুক্ত করার কোনও সুবিধা নেই const। এটি যা করে তা হ'ল:
    1. উত্স প্রয়োগকারীকে প্রতিবার সোর্স কোডে একটি ইনপুট প্যারাম পরিবর্তন করতে চাইলে একটি অনুলিপি তৈরি করতে সীমাবদ্ধ করুন (যা পরিবর্তিত হওয়ার কোনও পার্শ্ব প্রতিক্রিয়া হবে না কারণ যা পাস করেছে তা ইতিমধ্যে পাস-বাই-ভ্যালু হওয়ায় একটি অনুলিপি)। এবং প্রায়শই, একটি ইনপুট প্যারাম পরিবর্তন করে যা মান দ্বারা পাস হয় তা ফাংশন বাস্তবায়নের জন্য ব্যবহৃত হয়, তাই constসর্বত্র যোগ করা এটি বাধা দিতে পারে।
    2. এবং constঅযৌক্তিকভাবে কোডের সাথে কোথাও অস্থিরতা যুক্ত করে নিরাপদ কোড থাকা সত্যিকার অর্থে প্রয়োজনীয় এস এর constথেকে দৃষ্টি আকর্ষণ করা const
  2. যখন সঙ্গে তার আচরণ পয়েন্টার বা রেফারেন্স , তবে, constসমালোচকদের গুরুত্বপূর্ণ প্রয়োজন হলে, এবং আবশ্যক ব্যবহার করা যেতে, যেমন ক্রমাগত পরিবর্তনের সঙ্গে অবাঞ্ছিত পার্শ্ব প্রতিক্রিয়া বাধা দেয় বাহিরে ফাংশন, এবং সেইজন্য প্রতি একক পয়েন্টার বা রেফারেন্স আবশ্যক ব্যবহার constযখন parm একটি ইনপুট শুধুমাত্র হয়, আউটপুট না। const কেবলমাত্র রেফারেন্স বা পয়েন্টার দ্বারা পাস হওয়া প্যারামিটারগুলিতে ব্যবহার করে প্যারামিটারগুলি পয়েন্টার বা রেফারেন্সগুলি এটি সত্যরূপে সুস্পষ্ট করার অতিরিক্ত সুবিধা রয়েছে । "নজর রাখুন! এর constপাশের কোনও পরম হল একটি রেফারেন্স বা পয়েন্টার!"!
  3. উপরে আমি যা বর্ণনা করেছি তা আমি প্রায়শই পেশাদার সফ্টওয়্যার সংস্থাগুলিতে কাজ করেছি যেগুলির মধ্যে sensকমত্য হয়েছে এবং এটি সর্বোত্তম অনুশীলন হিসাবে বিবেচিত হয়েছে। কখনও কখনও এমনকি, নিয়মটি কঠোর ছিল: "মান দ্বারা পাস হওয়া পরামিতিগুলির ক্ষেত্রে কখনও কনস্ট ব্যবহার করবেন না, তবে কেবল ইনপুট হলে রেফারেন্স বা পয়েন্টার দ্বারা পাস হওয়া পরামিতিগুলিতে সর্বদা এটি ব্যবহার করুন" "

৩. গুগলের কথা (আমার সাথে একমত এবং সেরা উত্তরের):

(" গুগল সি ++ স্টাইল গাইড " থেকে)

মান দ্বারা প্রদত্ত একটি ফাংশন প্যারামিটারের জন্য, কলারের উপর কনস্টের কোনও প্রভাব থাকে না, সুতরাং ফাংশন ঘোষণায় এটি প্রস্তাবিত নয়। দেখুন TotW # 109

স্থানীয় ভেরিয়েবলগুলিতে কনস্ট ব্যবহার করা উত্সাহিত বা নিরুৎসাহিত নয়।

উত্স: গুগল সি ++ স্টাইল গাইডের "কনস্টের ব্যবহার" বিভাগ: https://google.github.io/styleguide/cppguide.html#Use_of_const । এটি আসলেই একটি মূল্যবান বিভাগ, সুতরাং পুরো বিভাগটি পড়ুন।

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

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

৪. ক্ল্যাংয়ের লিটারের clang-tidyকাছে এর জন্য কিছু বিকল্প রয়েছে:

উ: এরও কোন মূল্য নেই যে ঝনঝন এর Linter, মূল্য clang-tidyরয়েছে, একটি বিকল্প readability-avoid-const-params-in-decls, এখানে বর্ণিত , সমর্থন করার জন্য একটি কোড বেস মধ্যে প্রয়োগ না ব্যবহার constপাস-বাই-মান ফাংশন পরামিতি জন্য :

কোনও ফাংশন ঘোষণায় পরামিতিগুলি শীর্ষ স্তরের কনস্ট রয়েছে কিনা তা পরীক্ষা করে।

ঘোষণায় কনস্ট মানগুলি কোনও ফাংশনের স্বাক্ষরকে প্রভাবিত করে না তাই তাদের সেখানে রাখা উচিত নয় be

উদাহরণ:

void f(const string);   // Bad: const is top level.
void f(const string&);  // Good: const is not top level.

এবং এখানে আরও দুটি উদাহরণ আমি সম্পূর্ণতা এবং স্পষ্টতার জন্য নিজেকে যুক্ত করছি:

void f(char * const c_string);   // Bad: const is top level. [This makes the _pointer itself_, NOT what it points to, const]
void f(const char * c_string);   // Good: const is not top level. [This makes what is being _pointed to_ const]

বি এরও এই বিকল্প রয়েছে: readability-const-return-type- https://clang.llvm.org/extra/clang-tidy/checks/readability-const-return-type.html

৫. আমি কীভাবে বিষয়টি সম্পর্কে একটি শৈলী নির্দেশিকা বলতে পারি তার বিষয়ে আমার ব্যবহারিক পদ্ধতি:

আমি কেবল এটিকে অনুলিপি করে আমার স্টাইল গাইডে আটকে দিতে চাই:

[কপি / পেস্ট শুরু]

  1. constরেফারেন্স বা পয়েন্টার দ্বারা পাস করা ফাংশন পরামিতিগুলিতে সর্বদা ব্যবহার করুন যখন তাদের বিষয়বস্তুগুলি (তারা কী দেখায়) পরিবর্তিত না হওয়ার উদ্দেশ্যে করা হয়। এইভাবে, এটি স্পষ্ট হয়ে ওঠে যখন রেফারেন্স বা পয়েন্টার দ্বারা পাস করা কোনও ভেরিয়েবল পরিবর্তিত হবে বলে আশা করা হয়, কারণ এর অভাব হবে const। এই ক্ষেত্রে ক্ষেত্রে constফাংশনের বাইরে দুর্ঘটনাজনিত পার্শ্ব প্রতিক্রিয়া প্রতিরোধ করে।
  2. এটি মান দ্বারা পাস ফাংশন পরামিতি ব্যবহার করার পরামর্শ দেওয়া হয় নাconst , কারণ constকলারের উপর কোনও প্রভাব নেই: এমনকি ফাংশনে ভেরিয়েবল পরিবর্তন করা হলেও ফাংশনের বাইরে কোনও পার্শ্ব প্রতিক্রিয়া থাকবে না will অতিরিক্ত ন্যায়সঙ্গততা এবং অন্তর্দৃষ্টি জন্য নিম্নলিখিত সংস্থানগুলি দেখুন:
    1. "গুগল সি ++ স্টাইল গাইড" "কনস্টের ব্যবহার" বিভাগ
    2. "সপ্তাহের টিপ # 109: constফাংশন ঘোষণার ক্ষেত্রে অর্থবহ "
    3. "ফাংশন প্যারামিটারগুলির জন্য 'কনস্ট' ব্যবহারের বিষয়ে অ্যাডিসাকের স্ট্যাক ওভারফ্লো উত্তর
  3. " সংজ্ঞা নয় এমন ঘোষণাপত্রে ফাংশন প্যারামিটারগুলিতে কখনও শীর্ষ স্তরের const[যেমন: মান দ্বারাconst পরামিতিগুলিতে ] ব্যবহার করবেন না (এবং অর্থহীন অনুলিপি / অনুলিপি করার বিষয়ে সতর্ক থাকুন ) the এটি সংকলক দ্বারা অর্থহীন এবং উপেক্ষা করা হয়, এটি চাক্ষুষ শব্দ , এবং এটি পাঠকদের বিভ্রান্ত করতে পারে "( https://abseil.io/tips/109 , জোর যুক্ত করা হয়েছে)। const
    1. constসংকলনের উপর প্রভাব ফেলে কেবলমাত্র বাছাইকারীরা হ'ল ফাংশন সংজ্ঞায় স্থাপন করা, ফাংশনের অগ্রিম ঘোষণায় যেমন নয়, যেমন একটি শিরোনাম ফাইলে কোনও ফাংশন (পদ্ধতি) ঘোষণায়।
  4. কখনও ব্যবহার টপ লেভেল const: [অর্থাত constভেরিয়েবল উপর মান দ্বারা গৃহীত মূল্যবোধ] ফিরে একটি ফাংশন দ্বারা।
  5. constকোনও ফাংশন দ্বারা ফিরিয়ে দেওয়া পয়েন্টার বা রেফারেন্স ব্যবহার করা প্রয়োগকারীর উপর নির্ভরশীল , কারণ এটি কখনও কখনও দরকারী।
  6. টোডো: নিম্নলিখিত clang-tidyবিকল্পগুলির সাথে উপরের কয়েকটি প্রয়োগ করুন:
    1. https://clang.llvm.org/extra/clang-tidy/checks/readability-avoid-const-params-in-decls.html
    2. https://clang.llvm.org/extra/clang-tidy/checks/readability-const-return-type.html

constউপরে বর্ণিত বিধিগুলি প্রদর্শনের জন্য এখানে কয়েকটি কোড উদাহরণ রয়েছে :

constপ্যারামিটার উদাহরণ:
(কিছু এখান থেকে ধার করা হয় )

void f(const std::string);   // Bad: const is top level.
void f(const std::string&);  // Good: const is not top level.

void f(char * const c_string);   // Bad: const is top level. [This makes the _pointer itself_, NOT what it points to, const]
void f(const char * c_string);   // Good: const is not top level. [This makes what is being _pointed to_ const]

constরিটার্ন ধরণের উদাহরণ:
(কিছু এখান থেকে ধার করা হয়েছে )

// BAD--do not do this:
const int foo();
const Clazz foo();
Clazz *const foo();

// OK--up to the implementer:
const int* foo();
const int& foo();
const Clazz* foo();

[কপি / পেস্ট শেষ]


2

আপনি যে ক্ষেত্রে উল্লেখ করেছেন, এটি আপনার এপিআই এর কলকারীদের প্রভাবিত করে না, এজন্য এটি সাধারণত করা হয় না (এবং শিরোনামে প্রয়োজনীয় নয়)। এটি কেবলমাত্র আপনার ক্রিয়াকলাপ বাস্তবায়নকে প্রভাবিত করে।

এটি করা বিশেষত খারাপ কাজ নয়, তবে এটিগুলি আপনার এপিআইকে প্রভাবিত করে না এবং এটি টাইপিং যুক্ত করে, তবে এটি সাধারণত করা হয় না তবে সুবিধাগুলি এতটা দুর্দান্ত নয় great


2

আমি মান-পাস করা প্যারামিটারের জন্য কনস্ট ব্যবহার করি না। আপনি প্যারামিটারটি সংশোধন করেছেন কিনা তা কলারের যত্নশীল নয়, এটি বাস্তবায়নের বিশদ।

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

আমি যদি স্থানীয় সংস্করণগুলি চিহ্নিত করার প্রয়োজন না হয় সেগুলিও চিহ্নিত করি। আমার বিশ্বাস, "চলমান অংশগুলি" সনাক্ত করা সহজ করে কোডটি বোঝা সহজ করে তোলে।



2

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


2

সংক্ষেপ:

  • "সাধারণত পাস-বাই-মানটি অব্যবহারযোগ্য এবং সর্বোত্তমভাবে বিভ্রান্তিকর" " GOTW006 থেকে
  • তবে আপনি এগুলি .cpp এ যোগ করতে পারেন যেমন আপনি ভেরিয়েবলগুলির সাথে করেন।
  • নোট করুন যে স্ট্যান্ডার্ড লাইব্রেরি কনস্ট ব্যবহার করে না। যেমন std::vector::at(size_type pos)। স্ট্যান্ডার্ড লাইব্রেরির জন্য যা যথেষ্ট তা আমার পক্ষে ভাল।

2
"স্ট্যান্ডার্ড লাইব্রেরির জন্য যা যথেষ্ট তা আমার পক্ষে ভাল" সর্বদা সত্য নয়। উদাহরণস্বরূপ, স্ট্যান্ডার্ড লাইব্রেরি _Tmpসর্বকালের মতো কুৎসিত পরিবর্তনশীল নামগুলি ব্যবহার করে - আপনি এটি চান না (আসলে আপনি এগুলি ব্যবহারের অনুমতি নেই)।
অ্যানাটলিগ

1
@নাটোলিগ এটি একটি বাস্তবায়ন বিশদ
ফার্নান্দো পেলেসিওনি

2
ঠিক আছে, উভয় ভেরিয়েবলের নাম এবং যুক্তি তালিকার কনস্ট-কোয়ালিড টাইপগুলি বাস্তবায়ন বিশদ। আমি যা বলতে চাই তা হল, স্ট্যান্ডার্ড লাইব্রেরির প্রয়োগ কখনও কখনও ভাল হয় না। কখনও কখনও, আপনি আরও ভাল (এবং করা উচিত) করতে পারেন। স্ট্যান্ডার্ড লাইব্রেরির কোডটি কখন লেখা হয়েছিল - 10 বছর আগে? 5 বছর আগে (এর কিছু নতুন অংশ)? আমরা আজ আরও ভাল কোড লিখতে পারি।
anatolyg

1

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

আমি .h / .cpp ফাইল ঘোষণার পার্থক্য সম্পর্কে জানতাম না, তবে এটি কিছুটা অর্থপূর্ণ। মেশিন কোড স্তরে, কোনও কিছুই "কনস্ট" নয়, সুতরাং আপনি যদি কোনও ফাংশন (.h) তে নন-কনস্ট হিসাবে ঘোষণা করেন তবে কোডটি সমান (যদি আপনি এটি কনস্টেন্ট হিসাবে ঘোষণা করেন) তবে একই রকম। যাইহোক, এটি আপনাকে সংকলক তালিকাভুক্ত করতে সহায়তা করে যে আপনি ফাংশন (.ccp) বাস্তবায়নের অভ্যন্তরে ভেরিয়েবলের মান পরিবর্তন করবেন না। আপনি যখন এমন ইন্টারফেস থেকে উত্তরাধিকার সূত্রে পরিবর্তন আনতে পারেন তখন এটি কার্যকর হতে পারে তবে প্রয়োজনীয় কার্যকারিতা অর্জনের জন্য আপনাকে প্যারামিটারে পরিবর্তন করতে হবে না।


0

আমি এই জাতীয় পরামিতিগুলিতে দৃ const়তা রাখব না - প্রত্যেকে ইতিমধ্যে জানে যে একটি বুলিয়ান (বুলিয়ান এবং এর বিপরীতে) ধ্রুবক, তাই এটি যুক্ত করা লোককে "অপেক্ষা কর, কী?" বা এমনকি আপনি রেফারেন্স দ্বারা পরামিতি পাস করছেন।


4
কখনও কখনও আপনি রেফারেন্সের মাধ্যমে কোনও বস্তু পাস করতে চান (পারফরম্যান্সের কারণে) তবে এটি পরিবর্তন করতে পারবেন না, সুতরাং কনস্ট তখন বাধ্যতামূলক। এই জাতীয় সমস্ত পরামিতি - এমনকি বুলস - কনস্ট্যান্ট রাখার পরে আপনার কোডটি পড়া সহজ করে দেওয়া ভাল অনুশীলন হবে।
gbjbaanb

0

কনস্টের সাথে মনে রাখার বিষয়টি হল যে চেষ্টাগুলি করা এবং পরে এগুলি স্থাপনের চেয়ে বিষয়গুলি শুরু থেকে তৈরি করা অনেক সহজ।

আপনি যখন কোনও কিছু অপরিবর্তিত রাখতে চান তখন কনস্ট ব্যবহার করুন - এটি একটি যুক্ত ইঙ্গিত যা আপনার ফাংশনটি কী করবে এবং কী প্রত্যাশা করবে তা বর্ণনা করে। আমি অনেকগুলি সিআইপি দেখেছি যা তাদের মধ্যে কিছুর মতো করতে পারে, বিশেষত সি-স্ট্রিংগুলি গ্রহণ করে!

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


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

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

0

ফাংশনটি যেভাবেই চলকটির অনুলিপি পরিবর্তন করতে পারে কারণ একটি মান-পরামিতি "কনস্ট" তৈরি করার কোনও কারণ নেই।

"কনস্ট" ব্যবহারের কারণটি হ'ল যদি আপনি রেফারেন্সের মাধ্যমে বড় কিছু (উদাহরণস্বরূপ প্রচুর সদস্য সহ একটি স্ট্রাক্ট) পাস করেন তবে এক্ষেত্রে এটি নিশ্চিত করে যে ফাংশনটি এটি পরিবর্তন করতে পারে না; বা পরিবর্তে, সংকলক অভিযোগ করবেন যদি আপনি এটি প্রচলিত উপায়ে পরিবর্তন করার চেষ্টা করেন। এটি দুর্ঘটনাক্রমে সংশোধন হতে বাধা দেয়।


0

কনস্ট্রাক্ট প্যারামিটার কেবল তখনই দরকারী যখন প্যারামিটারটি রেফারেন্স দ্বারা যেমন পাস করা হয়, হয় রেফারেন্স বা পয়েন্টার দ্বারা। কম্পাইলার যখন কোনও কনস্ট প্যারামিটার দেখে, তখন তা নিশ্চিত করে যে প্যারামিটারে ব্যবহৃত ভেরিয়েবলটি ফাংশনের মূল অংশের মধ্যে পরিবর্তন করা হয়নি। কেন কেউ ধ্রুবক হিসাবে বাই-ভ্যালু প্যারামিটার তৈরি করতে চাইবে? :-)


অনেক কারণে. মেকিং একটি বাই-মান পরামিতি constস্পষ্টভাবে বলে: 'তাই আমি যে ঘোষণা করছি আমি এই পরিবর্তন করতে হবে না। আমি যদি পরে এটি সংশোধন করার চেষ্টা করি তবে আমাকে একটি সংকলন-সময় ত্রুটি দিন যাতে আমি হয় আমার ভুলটি ঠিক করতে পারি বা এর চিহ্নটি চিহ্নিত করতে পারি const'' সুতরাং এটি উভয় কোড স্বাস্থ্যবিধি এবং সুরক্ষার বিষয়। বাস্তবায়নের ফাইলগুলিতে যোগ করার জন্য যা কিছু লাগে তার জন্য, এটি শুদ্ধ প্রতিচ্ছবি, আইএমও হিসাবে লোকেদের কিছু করা উচিত।
আন্ডারস্কোর_

0

মান হিসাবে প্যারামিটারগুলি পাস হচ্ছে, আপনি কলিং ফাংশনটির দৃষ্টিকোণ থেকে কনস্ট বা নির্দিষ্ট না করে কোনও পার্থক্য তৈরি করবে না bas এটি মূলত কনস্টেন্ট হিসাবে মান পরামিতি দ্বারা পাস ঘোষণার কোনও মানে হয় না।


0

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

সুতরাং আমি অতিরিক্ত কনসাল্ট এড়িয়ে চলতাম কারণ

  • তারা নিরর্থক
  • তারা পাঠ্য বিশৃঙ্খলা
  • তারা আমাকে সেই ক্ষেত্রে কার্যকর বা দক্ষ হতে পারে এমন ক্ষেত্রে মান পাসের পরিবর্তনে বাধা দেয়।

-1

আমি জানি প্রশ্নটি "কিছুটা" পুরানো, কিন্তু আমি যখন এটির সামনে এসেছি তখন ভবিষ্যতে অন্য কেউ এটিও করতে পারে ... ... তবুও আমি সন্দেহ করি যে দরিদ্র লোকটি এখানে আমার মন্তব্য পড়ার জন্য এখানে নীচে তালিকাবদ্ধ করবে :)

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

#include <iostream>

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class SharedBuffer {
private:

  int fakeData;

  int const & Get_(int i) const
  {

    std::cout << "Accessing buffer element" << std::endl;
    return fakeData;

  }

public:

  int & operator[](int i)
  {

    Unique();
    return const_cast<int &>(Get_(i));

  }

  int const & operator[](int i) const
  {

    return Get_(i);

  }

  void Unique()
  {

    std::cout << "Making buffer unique (expensive operation)" << std::endl;

  }

};

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void NonConstF(SharedBuffer x)
{

  x[0] = 1;

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void ConstF(const SharedBuffer x)
{

  int q = x[0];

}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int main()
{

  SharedBuffer x;

  NonConstF(x);

  std::cout << std::endl;

  ConstF(x);

  return 0;

}

PS: আপনি যুক্তি দিতে পারেন যে (কনস্ট্যান্ট) রেফারেন্সটি এখানে আরও উপযুক্ত হবে এবং আপনাকে একই আচরণ দেয়। ঠিক আছে, ঠিক আছে। আমি অন্য কোথাও যা দেখতে পাচ্ছিলাম তার থেকে কেবল আলাদা চিত্র দেওয়া হচ্ছে ...

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