আকর্ষণীয় উত্তর: যদিও আমি তাদের সকলের সাথে একমত (এখনও অবধি), এই প্রশ্নের সম্ভাব্য অভিব্যক্তিগুলি রয়েছে যা এখন পর্যন্ত সম্পূর্ণ অবহেলিত।
উপরের সরল উদাহরণটি যদি সম্পদ বরাদ্দের সাথে প্রসারিত করা হয়, এবং তারপরে ত্রুটিগুলি পরীক্ষা করে সম্ভাব্য ফলস্বরূপ সংস্থানগুলি মুক্ত করা হয় তবে চিত্রটি পরিবর্তন হতে পারে।
নিখুঁত পদ্ধতির বিবেচনা করুন প্রাথমিকভাবে গ্রহণকারীরা নিতে পারে:
int func(..some parameters...) {
res_a a = allocate_resource_a();
if (!a) {
return 1;
}
res_b b = allocate_resource_b();
if (!b) {
free_resource_a(a);
return 2;
}
res_c c = allocate_resource_c();
if (!c) {
free_resource_b(b);
free_resource_a(a);
return 3;
}
do_work();
free_resource_c(c);
free_resource_b(b);
free_resource_a(a);
return 0;
}
উপরোক্ত সময়ের পূর্বে ফিরে আসার শৈলীর চূড়ান্ত সংস্করণ উপস্থাপন করবে। লক্ষ্য করুন যে কীভাবে কোডটির জটিলতা বাড়তে থাকে সময়ের সাথে সাথে এটি খুব পুনরাবৃত্তিযোগ্য এবং অ-রক্ষণাবেক্ষণযোগ্য হয়ে যায়। আজকাল মানুষ এগুলি ধরতে ব্যতিক্রম হ্যান্ডলিং ব্যবহার করতে পারে।
int func(..some parameters...) {
res_a a;
res_b b;
res_c c;
try {
a = allocate_resource_a(); # throws ExceptionResA
b = allocate_resource_b(); # throws ExceptionResB
c = allocate_resource_c(); # throws ExceptionResC
do_work();
}
catch (ExceptionBase e) {
# Could use type of e here to distinguish and
# use different catch phrases here
# class ExceptionBase must be base class of ExceptionResA/B/C
if (c) free_resource_c(c);
if (b) free_resource_b(b);
if (a) free_resource_a(a);
throw e
}
return 0;
}
ফিলিপ নীচের গোটো উদাহরণটি দেখার পরে পরামর্শ দিয়েছেন, উপরের ক্যাচ ব্লকের অভ্যন্তরে ব্রেক-কম সুইচ / কেস ব্যবহার করতে । কেউ সুইচ (টাইফফ (ই)) করতে পারে এবং তারপরে free_resourcex()
কলগুলি পড়তে পারে তবে এটি তুচ্ছ নয় এবং ডিজাইনের বিবেচনার প্রয়োজন । এবং মনে রাখবেন যে বিরতি ছাড়াই একটি স্যুইচ / কেস হ'ল নীচে ডেইজি-চেইন লেবেলগুলির সাথে গেটোয়ের মতো ...
মার্ক বি নির্দেশিত হিসাবে, সি ++ এ রিসোর্স অ্যাকুইজিশনটি ইনিশিয়ালাইজেশন নীতি, সংক্ষেপে আরআইআইআই অনুসরণ করা ভাল স্টাইল হিসাবে বিবেচিত হয় । ধারণার সংক্ষিপ্তসার হ'ল সম্পদ অর্জনের জন্য অবজেক্ট ইনস্ট্যান্টেশন ব্যবহার করা। বস্তুগুলি সুযোগের বাইরে চলে যাওয়ার সাথে সাথে তাদের ধ্বংসকারীদের ডাকা হওয়ার সাথে সাথে সংস্থানগুলি স্বয়ংক্রিয়ভাবে মুক্ত হয়। পরস্পরের উপর নির্ভরশীল সংস্থানগুলির জন্য অবনতির সঠিক ক্রম নিশ্চিত করার জন্য এবং প্রয়োজনীয় ধরণের ডেটা সমস্ত ধ্বংসকারীদের জন্য উপলব্ধ এমন ধরণের অবজেক্টের নকশার জন্য বিশেষ যত্ন নিতে হবে।
বা প্রাক ব্যতিক্রম দিনগুলিতে করতে পারে:
int func(..some parameters...) {
res_a a = allocate_resource_a();
res_b b = allocate_resource_b();
res_c c = allocate_resource_c();
if (a && b && c) {
do_work();
}
if (c) free_resource_c(c);
if (b) free_resource_b(b);
if (a) free_resource_a(a);
return 0;
}
তবে এই অতি-সরলকরণের উদাহরণটিতে বেশ কয়েকটি ত্রুটি রয়েছে: বরাদ্দকৃত সংস্থানগুলি একে অপরের উপর নির্ভর না করে তবেই এটি ব্যবহার করা যেতে পারে (উদাহরণস্বরূপ এটি মেমরি বরাদ্দকরণের জন্য ব্যবহার করা যায় না, তারপরে একটি ফাইলহ্যান্ডেল খোলার পরে হ্যান্ডেল থেকে মেমোরিতে ডেটা পড়া) ), এবং এটি পৃথক, পৃথক ত্রুটি কোডগুলি রিটার্ন মান হিসাবে সরবরাহ করে না।
কোডটি দ্রুত (!) রাখতে, কমপ্যাক্ট এবং সহজেই পঠনযোগ্য এবং এক্সটেনসিবল লিনাস টরভাল্ডস কার্নেল কোডের জন্য আলাদা স্টাইল প্রয়োগ করেছে যা সংস্থানসমূহের সাথে সম্পর্কিত, এমনকি কুখ্যাত গোটোকে এমনভাবে ব্যবহার করে যা একেবারে অর্থপূর্ণ :
int func(..some parameters...) {
res_a a;
res_b b;
res_c c;
a = allocate_resource_a() || goto error_a;
b = allocate_resource_b() || goto error_b;
c = allocate_resource_c() || goto error_c;
do_work();
error_c:
free_resource_c(c);
error_b:
free_resource_b(b);
error_a:
free_resource_a(a);
return 0;
}
কার্নেল মেলিং তালিকাগুলির আলোচনার মূল বক্তব্যটি হল যে বেশিরভাগ ভাষা বৈশিষ্ট্যগুলি গোটো স্টেটমেন্টের চেয়ে "পছন্দসই" থাকে তবে হ'ল বিশাল, গাছের মতো যদি / অন্য, ব্যতিক্রম হ্যান্ডলার, লুপ / ব্রেক / চালিয়ে যাওয়া বিবৃতি ইত্যাদি imp এবং উপরের উদাহরণটিতে গোটোকে ঠিক হিসাবে বিবেচনা করা হয়, যেহেতু তারা কেবল অল্প দূরত্বে চলেছে, পরিষ্কার লেবেল রয়েছে এবং ত্রুটির অবস্থার উপর নজর রাখার জন্য অন্যান্য বিশৃঙ্খলার কোড মুক্ত করে free এই প্রশ্নটি এখানে স্ট্যাকওভারফ্লো নিয়েও আলোচনা করা হয়েছে ।
তবে সর্বশেষ উদাহরণে যা অনুপস্থিত তা হ'ল একটি ত্রুটি কোড ফেরত দেওয়ার এক দুর্দান্ত উপায়। আমি result_code++
প্রতিটি free_resource_x()
কল করার পরে একটি যুক্ত করার এবং সেই কোডটি ফেরত দেওয়ার কথা ভাবছিলাম , তবে এটি উপরের কোডিং শৈলীর কিছু গতি অর্জনকে অফসেট করে। এবং সাফল্যের ক্ষেত্রে 0 ফিরিয়ে দেওয়া শক্ত। সম্ভবত আমি অকল্পনীয় ;-)
সুতরাং, হ্যাঁ, আমি মনে করি অকালব্যাপী রিটার্ন কোডিংয়ের প্রশ্নে একটি বড় পার্থক্য আছে। তবে আমি আরও মনে করি যে এটি কেবল আরও জটিল কোডে স্পষ্ট যে এটি সংকলকটির পুনর্গঠন এবং অনুকূলকরণ করা কঠিন বা অসম্ভব। সাধারণত একবারে যদি সম্পদ বরাদ্দ কার্যকর হয়।