সি ++ এ অপ্রয়োজনীয় কোঁকড়া ধনুর্বন্ধনী?


186

কোনও সহকর্মীর জন্য আজ কোড পর্যালোচনা করার সময় আমি একটি অদ্ভুত জিনিস দেখেছি। তিনি তার নতুন কোডটিকে এইভাবে কুঁকড়ানো ধনুর্বন্ধনী দিয়ে ঘিরেছিলেন:

Constructor::Constructor()
{
   existing code

   {
      New code: do some new fancy stuff here
   }

   existing code
}

এর থেকে কী হবে, যদি থাকে তবে? এটি করার কারণ কী হতে পারে? এই অভ্যাসটি কোথা থেকে আসে?

সম্পাদনা:

ইনপুট এবং নীচের কিছু প্রশ্নের উপর ভিত্তি করে আমার মনে হয়েছে যে আমি ইতিমধ্যে একটি উত্তর চিহ্নিত করেছি, যদিও আমাকে কিছু প্রশ্নের সাথে যুক্ত করতে হবে।

পরিবেশ এম্বেড করা ডিভাইস। সি ++ পোশাকের মোড়কে প্রচুর লিগ্যাসি সি কোড রয়েছে। অনেকগুলি সি টার্নড সি ++ বিকাশকারী রয়েছে।

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

কোঁকড়া ধনুর্বন্ধনী দ্বারা বেষ্টিত কোডটি হ'ল কিছু:

{
   bool isInit;
   (void)isStillInInitMode(&isInit);
   if (isInit) {
     return isInit;
   }
}

(কোডটিকে কিছু মনে করবেন না, কেবল কোঁকড়ানো ধনুর্বন্ধনীকে আটকে দিন ...;)) কোঁকড়া ধনুর্বন্ধনী পরে কিছু আরও বিড়ম্বনা, রাষ্ট্র চেকিং এবং বেসিক সিগন্যালিং রয়েছে।

আমি লোকটির সাথে কথা বলেছি এবং তার প্রেরণাটি ছিল ভেরিয়েবলের নাম, সংঘর্ষের নামকরণ এবং অন্য কিছু যা আমি সত্যিই তুলতে পারি না তা সীমাবদ্ধ করা।

আমার পিওভি থেকে এটি অদ্ভুত বলে মনে হচ্ছে এবং আমি মনে করি না যে কোঁকড়া ধনুর্বন্ধনী আমাদের কোডে থাকা উচিত। আমি কেন কোঁকড়া ধনুর্বন্ধনী সঙ্গে কোড ঘিরে করতে পারে সব উত্তরে কিছু ভাল উদাহরণ দেখেছি, কিন্তু আপনি কোড পরিবর্তে পদ্ধতিতে আলাদা করা উচিত নয়?


98
আপনি যখন তাকে জিজ্ঞাসা করলেন কেন তিনি এটি করেছিলেন কেন আপনার সহকর্মীর জবাব ছিল?
গ্রাহাম বোরল্যান্ড

20
RAII প্যাটার্নের সাথে বেশ সাধারণ। দ্রুত ওভারভিউ: c2.com/cgi/wiki?SourceAAquictIIIIitialization
মার্সিন

9
আমি অপ্রয়োজনীয় কোঁকড়া ধনুর্বন্ধনী ঘৃণা করি
jacknad

8
অভ্যন্তরীণ ব্লকে কি কোনও ঘোষণা ছিল?
কিথ থম্পসন

15
সম্ভবত তিনি সহজেই সম্পাদকের সেই নতুন বিভাগটি সহজেই 'ভাঁজ' করতে চেয়েছিলেন
উইম

উত্তর:


280

এটি কখনও কখনও দুর্দান্ত কারণ এটি আপনাকে একটি নতুন সুযোগ দেয়, যেখানে আপনি আরও "পরিষ্কারভাবে" নতুন (স্বয়ংক্রিয়) ভেরিয়েবলগুলি ঘোষণা করতে পারেন।

ইন C++এই হয়তো তাই গুরুত্বপূর্ণ নয় যেহেতু আপনি নতুন ভেরিয়েবলের জন্য যে কোন জায়গায় পরিচয় করিয়ে দিতে পারেন, কিন্তু সম্ভবত অভ্যাস থেকে C, যেখানে আপনি C99 পর্যন্ত এই কাজ করতে পারে না। :)

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


37
নতুন ভেরিয়েবল এবং পুরানো অভ্যাসের স্পষ্ট উল্লেখের জন্য +1
আরনে

46
যত দ্রুত সম্ভব সম্পদ মুক্ত করতে ব্লক স্কোপ ব্যবহার করার জন্য +1
লিও

9
এটি 'যদি (0)' ব্লক করাও সহজ।
vrdhn

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

21
@ এসসনড্যাকড, তারা আপনাকে বলে যে আপনার পদ্ধতিগুলি "খুব সংক্ষিপ্ত"? এটি করা অত্যন্ত কঠিন। 90% বিকাশকারী (আমার সম্ভবত অন্তর্ভুক্ত) এর বিপরীত সমস্যা রয়েছে।
বেন লি

169

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


14
অবশ্যই, এই ব্লকটি কেবল একটি পৃথক ফাংশন হিসাবে তৈরি করা উচিত।
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

8
Noteতিহাসিক দ্রষ্টব্য: এটি প্রাথমিক সি ভাষা থেকে প্রাপ্ত একটি কৌশল যা স্থানীয় অস্থায়ী ভেরিয়েবলগুলি তৈরি করতে দেয়।
থমাস ম্যাথিউজ

12
আমাকে বলতে হবে - যদিও আমি আমার উত্তর নিয়ে সন্তুষ্ট, এটি এখানে সেরা উত্তর নয়; সবচেয়ে ভালো উত্তর স্পষ্টভাবে RAII উল্লেখ যেহেতু এটি মূল কারণ কেন আপনি চান সেটি বিনাশকারী একটি নির্দিষ্ট সময়ে বলা হবে। এটি "পশ্চিমের দ্রুততম বন্দুক" এর মতো একটি ঘটনা বলে মনে হচ্ছে: আমি যথেষ্ট দ্রুত পোস্ট করেছি যে আমি আরও প্রাথমিক উত্তোলন পেয়েছি যে আরও ভাল উত্তরের চেয়ে দ্রুত গতিতে অর্জন করতে "গতি" পেয়েছি। এমন নয় যে আমি অভিযোগ করছি! :-)
রুখ

7
@ ব্লুরাজা-ড্যানি ফ্লুঘুফুট আপনি ওভারসিম্লিফাইটিং করছেন। "এটিকে একটি পৃথক ফাংশনে রাখুন" প্রতিটি কোড সমস্যার সমাধান নয়। এর মধ্যে একটি ব্লকের কোডটি পার্শ্ববর্তী কোডের সাথে এর বেশ কয়েকটি ভেরিয়েবলের সাথে স্পর্শ করে শক্তভাবে সংযুক্ত হতে পারে touch সি ফাংশন ব্যবহার করে, এর জন্য পয়েন্টার অপারেশন প্রয়োজন। তদুপরি, প্রতিটি কোড স্নিপেট পুনরায় ব্যবহারযোগ্য হয় না (এবং হওয়া উচিত) এবং কখনও কখনও কোডটি নিজের মতো করেও বোঝায় না। আমি মাঝে মাঝে সি 98 for-এ একটি স্বল্প- int i;কালীন তৈরি করতে আমার বক্তব্যগুলির চারপাশে ব্লকগুলি রেখেছি । অবশ্যই আপনি পরামর্শ দিচ্ছেন না যে প্রত্যেককে forআলাদা আলাদা ফাংশনে থাকা উচিত?
Anders Sjöqvist

101

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

আমার প্রোডাকশন কোডে, আমি এই জাতীয় কিছু লিখেছি:

void f()
{
   //some code - MULTIPLE threads can execute this code at the same time

   {
       scoped_lock lock(mutex); //critical section starts here

       //critical section code
       //EXACTLY ONE thread can execute this code at a time

   } //mutex is automatically released here

  //other code  - MULTIPLE threads can execute this code at the same time
}

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


1
আমি মনে করি এটি কেবল পরিষ্কার হওয়া উচিত: স্কোপড_লক লক (মিটেক্স) // সমালোচনামূলক বিভাগ কোড তারপর লক.নলক ()।
সিজল

17
@ জাজিলেনস্কি: সমালোচনা বিভাগের কোড ব্যতিক্রম ছুঁড়ে ফেললে কী হবে? হয় মিটেক্স চিরতরে লক হয়ে যাবে, বা কোড আপনি যে কথা বলেছিলেন তেমন ক্লিনার হবে না ।
নওয়াজ

4
@ নওয়াজ: @ সিজিলেনস্কির এই ব্যতিক্রম ব্যতিক্রমের ক্ষেত্রে মুটেক্সকে তালাবদ্ধ রাখবে না। তিনি এমন একটি ব্যবহার করেন scoped_lockযা ব্যতিক্রমগুলিতে ধ্বংস হয়ে যায়। আমি সাধারণত লকটির জন্য একটি নতুন সুযোগ প্রবর্তন করতে পছন্দ করি তবে কিছু ক্ষেত্রে এটি unlockখুব দরকারী। উদাহরণস্বরূপ, সমালোচনামূলক বিভাগের মধ্যে একটি নতুন স্থানীয় ভেরিয়েবল ঘোষণা এবং তারপরে এটি ব্যবহার করুন। (আমি জানি আমি দেরি করেছি, তবে কেবল সম্পূর্ণতার জন্য ...)
স্টিফান

51

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

তবে এটি করার আরও একটি দুর্দান্ত কারণ রয়েছে fine

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

  • এই অংশটির একটি সুসংগত ধারণাগত উদ্দেশ্য রয়েছে
  • এখানে সমস্ত কোড প্রয়োজনীয়
  • এবং এখানে অংশ সম্পর্কে একটি মন্তব্য।

যেমন

{  // update the moving average
   i= (i+1) mod ARRAYSIZE;
   sum = sum - A[i];
   A[i] = new_value;
   sum = sum + new_value;
   average = sum / ARRAYSIZE ;  
}

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

আপনি যদি ভাগ্যবান হন তবে আপনার সম্পাদকের একটি ভাঁজ / ফোল্ডোল ফাংশন থাকবে যা আপনাকে ব্লকটি আড়াল করতে দেয়।

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


23

একটি কারণ হতে পারে যে নতুন কোঁকড়া ধনুর্বন্ধনী ব্লকের ভিতরে ঘোষিত যে কোনও ভেরিয়েবলের আজীবন এই ব্লকের মধ্যে সীমাবদ্ধ। আরেকটি কারণ যা মনে আসে তা হ'ল প্রিয় সম্পাদকটিতে কোড ফোল্ডিং ব্যবহার করতে সক্ষম হওয়া।


17

এটি একটি if(বা whileইত্যাদি ..) ব্লকের মতো, ঠিক ছাড়াই if । অন্য কথায়, আপনি একটি নিয়ন্ত্রণ কাঠামো প্রবর্তন না করে একটি সুযোগ প্রবর্তন।

এই "সুস্পষ্ট স্কোপিং" নিম্নলিখিত ক্ষেত্রে সাধারণত কার্যকর হয়:

  1. নাম সংঘর্ষ এড়াতে।
  2. সুযোগ আছে using
  3. ধ্বংসকারীদের ডাকা হলে নিয়ন্ত্রণ করতে control

উদাহরণ 1:

{
    auto my_variable = ... ;
    // ...
}

// ...

{
    auto my_variable = ... ;
    // ...
}

যদি my_variableকোনো একটি উন্নত মানের হতে হবে নাম দুটি ভিন্ন ভেরিয়েবল যে একে অপরের থেকে বিচ্ছিন্নতা ব্যবহার করা হয়, তারপর স্পষ্ট scoping তোমাকে একটা নতুন নামে উদ্ভাবন শুধু নাম সংঘর্ষ এড়াতে এড়াতে পারেন।

এটি আপনাকে my_variableদুর্ঘটনাক্রমে এর উদ্দেশ্যযুক্ত সুযোগটি ব্যবহার করা এড়াতে দেয় ।

উদাহরণ 2:

namespace N1 { class A { }; }
namespace N2 { class A { }; }

void foo() {

    {
        using namespace N1;
        A a; // N1::A.
        // ...
    }

    {
        using namespace N2;
        A a; // N2::A.
        // ...
    }

}

ব্যবহারিক পরিস্থিতিতে যখন এটি কার্যকর হয় বিরল এবং এটি নির্দেশ করতে পারে কোডটি রিফ্যাক্টরিংয়ের জন্য উপযুক্ত, তবে সেখানে এমন প্রক্রিয়া রয়েছে যা আপনার সত্যিকারের প্রয়োজন হবে need

উদাহরণ 3:

{
    MyRaiiClass guard1 = ...;

    // ...

    {
        MyRaiiClass guard2 = ...;
        // ...
    } // ~MyRaiiClass for guard2 called.

    // ...

} // ~MyRaiiClass for guard1 called.

এই ক্ষেত্রে RAII এর পক্ষে গুরুত্বপূর্ণ হতে পারে যখন যখন নিখরচায় সংস্থানগুলির প্রয়োজনীয়তা স্বাভাবিকভাবেই কার্যগুলি বা নিয়ন্ত্রণ কাঠামোর সীমানায় না পড়ে।


15

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


14

অন্য সবাই ইতিমধ্যে স্কোপিং, আরআইআইআই ইত্যাদি সম্ভাব্যতাগুলি সঠিকভাবে coveredেকে রেখেছে, তবে যেহেতু আপনি একটি এমবেডেড পরিবেশের কথা উল্লেখ করেছেন, তার আরও একটি সম্ভাব্য কারণ রয়েছে:

সম্ভবত বিকাশকারী এই সংকলকের নিবন্ধক বরাদ্দকে বিশ্বাস করে না বা একবারে স্কোপে স্বয়ংক্রিয় ভেরিয়েবলের সংখ্যা সীমিত করে স্ট্যাক ফ্রেমের আকারকে স্পষ্টভাবে নিয়ন্ত্রণ করতে চায়।

এখানে isInitসম্ভবত স্ট্যাক থাকবে:

{
   bool isInit;
   (void)isStillInInitMode(&isInit);
   if (isInit) {
     return isInit;
   }
}

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

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


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

11

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

// if (false) or if (0) 
{
   //experimental optimization  
}

এই অনুশীলনটি নির্দিষ্ট প্রসঙ্গে যেমন ডিবাগিং, এম্বেড থাকা ডিভাইসগুলি বা ব্যক্তিগত কোডে কার্যকর।


10

আমি "রুখ" এর সাথে একমত আপনি যদি সি এর বিভিন্ন স্তরের সুযোগের ভাল ব্যাখ্যা চান তবে এই পোস্টটি দেখুন:

সি প্রয়োগে বিভিন্ন স্তরের সুযোগ

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

int unusedInt = 1;

int main(void) {
  int k;

  for(k = 0; k<10; k++) {
    int returnValue = myFunction(k);
    printf("returnValue (int) is: %d (k=%d)",returnValue,k);
  }

  for(k = 0; k<100; k++) {
    char returnValue = myCharacterFunction(k);
    printf("returnValue (char) is: %c  (k=%d)",returnValue,k);
  }

  return 0;
}

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

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

অবশেষে, দয়া করে আমার কোডের নমুনায় ব্যবহৃত ভেরিয়েবলগুলির সুযোগ নোট করুন:

int:  unusedInt:   File and global scope (if this were a static int, it would only be file scope)
int:  k:           Function scope
int:  returnValue: Block scope
char: returnValue: Block scope

ব্যস্ত প্রশ্ন, মানুষ। আমার কখনই 100 টি উত্থান হয়নি। এই প্রশ্নটি সম্পর্কে বিশেষ কী? ভাল লিঙ্ক। সি ++ এর চেয়ে বেশি মূল্যবান।
ওল্ফপ্যাক'০৮

5

সুতরাং, "অপ্রয়োজনীয়" কোঁকড়া ধনুর্বন্ধনী ব্যবহার কেন?

  • "স্কোপিং" উদ্দেশ্যে (উপরে বর্ণিত হিসাবে)
  • কোনও উপায়ে কোডকে আরও পঠনযোগ্য করে তোলা ( #pragmaভিজ্যুয়ালাইজ করা যায় এমন "বিভাগগুলি" সংজ্ঞায়িত করার মতো )
  • কারন তুমি পারো. যে হিসাবে সহজ।

পিএস এটি বিএড কোড নয়; এটি 100% বৈধ সুতরাং, এটি বরং (অস্বাভাবিক) স্বাদের বিষয়।


5

সম্পাদনায় কোডটি দেখার পরে, আমি বলতে পারি যে অপ্রয়োজনীয় বন্ধনীগুলি সম্ভবত (মূল কোডার দর্শনে) 100% স্পষ্ট হতে হবে যদি / তারপরে কী হবে তবে এমনকি এটি এখন কেবল একটি লাইন, এটি হতে পারে আরও লাইন পরে, এবং বন্ধনীগুলি আপনাকে কোনও ত্রুটি করবে না তার গ্যারান্টি দেয়।

{
   bool isInit;
   (void)isStillInInitMode(&isInit);
   if (isInit) {
     return isInit;
   }
   return -1;
}

যদি উপরেরটি মূল ছিল, এবং "অতিরিক্ত" ওয়াডল অপসারণের ফলস্বরূপ:

{
   bool isInit;
   (void)isStillInInitMode(&isInit);
   if (isInit) 
     return isInit;
   return -1;
}

তারপরে, পরবর্তী কোনও পরিবর্তনটি এর মতো দেখতে পেল:

{
   bool isInit;
   (void)isStillInInitMode(&isInit);
   if (isInit) 
     CallSomethingNewHere();
     return isInit;
   return -1;
}

এবং এটি অবশ্যই একটি সমস্যা তৈরি করবে, যেহেতু এখনইআইনিট সর্বদা ফিরে আসবে, যদি / তবে তা নির্বিশেষে।


4

সুযোগগুলির বাইরে গেলে অবজেক্টগুলি স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যায় ...


2

ব্যবহারের আর একটি উদাহরণ ইউআই-সম্পর্কিত ক্লাসগুলি, বিশেষত Qt।

উদাহরণস্বরূপ, আপনার কাছে কিছু জটিল ইউআই এবং প্রচুর উইজেট রয়েছে, এদের প্রত্যেকের নিজের নিজস্ব স্পেসিং, লেআউট এবং ইত্যাদি পেয়েছে তাদের নামকরণের পরিবর্তে space1, space2, spaceBetween, layout1, ...আপনি কেবল পরিবর্তনশীলের অক্ষরযুক্ত নাম থেকে নিজেকে বাঁচাতে পারবেন যা কেবলমাত্র দুই-তিন লাইনে বিদ্যমান রয়েছে ables কোড।

ঠিক আছে, কেউ বলতে পারে যে আপনি এটি পদ্ধতিতে বিভক্ত করা উচিত, কিন্তু 40 টি পুনরায় ব্যবহারযোগ্য পদ্ধতি তৈরি করা ঠিক মনে হচ্ছে না - তাই আমি ঠিক করেছি যে তাদের সামনে কেবল ধনুর্বন্ধনী এবং মন্তব্য যুক্ত করব, সুতরাং এটি লজিক্যাল ব্লকের মতো দেখায়। উদাহরণ:

// Start video button 
{ 
   <here the code goes> 
}
// Stop video button
{
   <...>
}
// Status label
{
   <...>
}

এটি সেরা অনুশীলন বলতে পারি না তবে উত্তরাধিকারের কোডের পক্ষে এটি ভাল।

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

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