"নেমস্পেস ব্যবহার" দূষণ কী?


15

আমি গুগল কোডিং গাইড [এখানে] দেখছিলাম এবং তারা প্রস্তাব দেয় না যে কেউ এটি ব্যবহার করুন using namespaceবা namespace::function- যদি আমি এটির ভুল ব্যাখ্যা না করি।

এটিও কি প্রযোজ্য std? cout<<এটি ছাড়া কাজ করে না। এই বইটিও একই পরামর্শ দেয়। তাহলে আমি কীভাবে বা cout<<ছাড়া ব্যবহার করব ?using namespace std;std::cout<<

প্রস্তাবিত উপায় কি? std::cout<<? বেশিরভাগ সি ++ পাঠ্য বইয়ের সাথে শিখরদের শেখানো using namespace std;হয় তারা কি কোডিং অনুশীলনকে খারাপ প্রচার করছে?

উত্তর:


18

আমি যেমন গুগল স্ট্যান্ডার্ড পড়েছি, আপনি using namespace foo;নির্দেশটি কোথাও ব্যবহার করতে পারবেন না । এই নির্দেশিকাটি নেমস্পেসে ঘোষিত সমস্ত কিছু নিয়ে আসে এবং এটি সংঘর্ষ এবং অপ্রত্যাশিত আচরণের একটি সাধারণ কারণ। অন্যেরা খুব সাধারণ একটি উদ্ধৃত করেছেন: আপনার নিজের কোথাও নিজের সর্বোচ্চ বা ন্যূনতম পদ্ধতি রয়েছে এবং এটি কোনও এসআরসি ফাইলের সাথে সংঘর্ষ হয় যেখানে কেউ আপনার পদ্ধতির সাথে শিরোনাম অন্তর্ভুক্ত করে এবং তারপর বলেusing namespace std;

নির্দিষ্ট জায়গায়, এটির ব্যবহারের ঘোষণা দেওয়ার অনুমতি রয়েছে, যা রূপটি using ::foo::bar;

লোকেরা তাদের কোডগুলিতে নির্দেশাবলী ব্যবহার করতে পছন্দ করে কারণ এটি প্রচুর টাইপ করে, তবে এটি ঝুঁকি নিয়ে আসে। আপনার যদি প্রচুর পরিমাণে স্টাউট স্টেটমেন্ট সহ একটি ফাইল থাকে তবে আমি বুঝতে পারি না যে std :: cout একশ বার টাইপ করতে হবে, তবে আপনি কেবল :: std :: cout ব্যবহার করে বলতে পারেন। আমি এগুলি পরিবর্তনশীল ঘোষণার মতো আচরণ করি: যেখানে তাদের প্রয়োজন সেখানে স্কোপ করুন। যদি 10 টি ফাইলের একটি ফাংশনে আউটপুট লেখার প্রয়োজন হয় তবে শীর্ষে কাউট উপায়টি ঘোষণা করবেন না, এটি সেই ফাংশনে রাখুন যা আসল আউটপুট করছে।

#include <ostream>
//using namespace std; // NO!
//using ::std::cout;   // less bad than using namespace, but I prefer to scope it

int main(int argc, char** argv)
{
   int rc = do_some_stuff(argc, argv);
   using ::std::endl;
   if (rc) { // print the success report
      using ::std::cout;
      cout << "The test run completed. The return code was " << rc << '.' << endl;
    } else {
      using ::std::cerr;
      cerr << "Unable to complete the test run." << endl;
    }
    return 0 == rc;
}

এটি কয়েকটি চূড়ান্ত মাত্র কয়েক লাইন আউটপুট করছে তবে আপনি ধারণাটি পাবেন।

টাইপটি ছোট করার জন্য আর একটি জিনিস যা করা যায় তা হ'ল নাম বা টাইপিডেফ। আমি এসটিডি :: যাই হোক না কেন যে খারাপ হতে খুঁজে না, কিন্তু আমরা কয়েক ডজন মডিউলগুলির সাথে উৎস একটি বিশাল সেট আছে এবং কখনও কখনও আমরা মত লেখার কোড আছে console_gui::command_window::append("text")। এটি কিছুক্ষণ পরে ক্লান্তিকর হয়ে ওঠে এবং অনেকগুলি দীর্ঘ লাইন তৈরি করে। আমি সব কিছু যেমন কিছু জন্য

typedef console_gui::command_window cw;
cw::append("text");

এ্যালিয়াসগুলি যতক্ষণ না কোনও স্থানীয় স্কোপে সম্পন্ন হয় এবং কোডটি পাঠযোগ্য।


1
ধন্যবাদ! এটি সত্যই সহায়ক। আপনি কেবল সুন্দর উদাহরণ দিয়ে কেন খারাপ তা ব্যাখ্যা করেননি, তবে চমৎকার উদাহরণ সহ সমাধানগুলিও নির্দেশ করেছেন। :-)
লর্ড লোহ।

1
বিটিডাব্লু: std::endlসুস্পষ্ট ফ্লাশ চালু করার জন্য ব্যবহার করাstdout / এরstderr করা সাধারণত যথেষ্ট অতিরিক্ত অতিরিক্ত, সেই স্ট্রিমগুলি stdout/ stderrযাইহোক বাঁধা থাকে । এমনকি এটি কিছুটা ধীর করে দেয়।
Deduplicator

8

এর কারণ: 1) এটি নেমস্পেসের পুরো উদ্দেশ্যকে পরাস্ত করে, যা নামের সংঘাত হ্রাস করতে হয়; 2) এটি বিশ্বব্যাপী নেমস্পেসের সাথে ব্যবহারের নির্দেশের সাথে নির্দিষ্ট পুরো নামস্থানটি উপলব্ধ করে।

উদাহরণস্বরূপ, আপনি যদি নিজের সর্বাধিক () ফাংশন অন্তর্ভুক্ত করেন এবং সংজ্ঞা দেন তবে এটি স্টডি :: সর্বাধিক () এর সাথে সংঘর্ষ করবে।

http://en.cppreference.com/w/cpp/algorithm/max

পছন্দটি হ'ল স্ট্যান্ড :: সদস্য_ইউ_উইশ_টো_ইউজ ব্যবহার করা কারণ এটি স্পষ্টভাবে কোন নেমস্পেসটি ব্যবহার করতে হবে তা উল্লেখ করেছে।


আমি অনুমান করি এর অর্থ std::max()স্থানের উপসর্গ নামের সাথে আমার ব্যবহার করা উচিত । নাকি আমি ভুল করছি?
লর্ড লোহ

3
এর অর্থ হ'ল আপনি যদি "নেমস্পেস ব্যবহার করে std" রাখেন; আপনার কোডটিতে, আপনি নিজের সর্বোচ্চ ফাংশন (বা ইতিমধ্যে স্টাড নেমস্পেসে সংজ্ঞায়িত অন্য কোনও নাম) সংজ্ঞায়িত করলে আপনি ত্রুটিগুলি পেয়ে যাবেন
শেই গুম্বাল

1
এর অর্থ হ'ল usingনির্দেশের প্রতি আপনার সাবধানতা অবলম্বন করা উচিত কারণ এই ক্ষেত্রে এটি আপনার সর্বাধিক () ফাংশনটি ভেঙে ফেলবে যদি আপনি একটির সংজ্ঞা দিয়ে থাকেন এবং <algorithm> অন্তর্ভুক্ত করেন। এটি একটি সহজ কেস তবে আপনি কী করতে পারেন তা কখনই জানেন না break আপনি এটিটি ভেঙে ফেলেননি তা নিশ্চিত করার জন্য আপনাকে পুরো লাইব্রেরিটি জানতে হবে তবে ভবিষ্যতে আপনার কোডটি ভেঙে যাবে (অর্থাত্ নামটির সংঘাত) কিনা তা আপনি জানতে পারবেন না।
অ্যাপলপি

6

আপনার সরবরাহিত লিঙ্কটি উদ্ধৃত করে:

আপনি .cc ফাইলে এবং ফাংশন, পদ্ধতিতে বা .h ফাইলগুলিতে ক্লাসে যে কোনও জায়গায় ডিক্লেয়ারেশন ব্যবহার করতে পারেন।

// .cc ফাইলগুলিতে ঠিক আছে।

// .h ফাইলগুলিতে কোনও ফাংশন, পদ্ধতি বা শ্রেণিতে থাকতে হবে।

:: foo :: বার ব্যবহার করে;

গুগল স্টাইল আপনাকে বিশ্বব্যাপী প্রেক্ষাপটে নেমস্পেসগুলি আমদানি করতে নিষেধ করে, তবে স্থানীয় ক্ষেত্রে এটি করতে দেয়।

যেখানেই ঘোষণাপত্র ব্যবহার করা কোডের একটি সীমাবদ্ধ এবং স্পষ্টভাবে দৃশ্যমান অংশকেই প্রভাবিত করে এটি সর্বত্র গ্রহণযোগ্য।

আপনি যখন বিশ্বব্যাপী প্রসঙ্গকে দূষিত করেন, সম্পর্কহীন কোডটি প্রভাবিত হয় (আপনার শিরোনামটি ব্যবহার করে অনর্থক দ্বারা)। স্থানীয় প্রসঙ্গে আপনি যখন কিছুই করেন তখন কিছুই হয় না।


আমাদের একই মান রয়েছে। আমাদের কিছু লোক স্থানীয়ভাবে একটি দীর্ঘ নাম স্থান টাইপ করবে। যেমন টাইপেডেফ বোকা :: বার্লিয়াস এফবি; fb :: পানীয় d;
মাইকেল ম্যাথিউজ

1

তারা সুপারিশ করে না যে কেউ ব্যবহার করে নেমস্পেস ornamespace ব্যবহার করুন: ফাংশন` - যদি আমি এটির ভুল ব্যাখ্যা না করি।

তুমি করেছ. সিদ্ধান্তহীনতা কেবলমাত্র using namespaceনির্দেশের ক্ষেত্রে প্রযোজ্য (যা সাধারণত পরিহাসাত্মকভাবে abusing namespaceনয়, হিসাবে পরিচিত )। এটি দৃ strongly়ভাবে অগ্রাধিকার দেওয়া হয় যে আপনি কোনও ফাংশন বা অবজেক্টের পুরোপুরি যোগ্যতাসম্পন্ন নামটি ব্যবহার করুন std::cout


1

যদিও প্রশ্নটিতে ইতিমধ্যে দরকারী উত্তর রয়েছে তবে একটি বিশদটি খুব কম পড়েছে বলে মনে হচ্ছে।

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

নেমস্পেসের মধ্যে সনাক্তকারীগুলি স্পষ্টভাবে নেমস্পেসের নামকরণের মাধ্যমে অ্যাক্সেসযোগ্য:

myNamespace::myIdent

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

... অবশ্যই ঘোষণা ব্যবহারের মধ্যে একটি পার্থক্য আছে

using myNamespace::myIdent; // make myIdent an alias of myNamespace::myIdent

এবং নির্দেশ ব্যবহার করে

using myNamespace; // make all identifiers of myNamespace directly accessible

, এর আধুনিক বিশালাকার তাহলে বিশাল সুযোগ ব্যবহার করা অনেক বেশি বিহ্বলতায়।


1

আপনি এখানে যান:

#include <iostream>

int main()
{
    std::endl(std::operator<<(std::cout, "Hello world!"));
}

এটি এইভাবে লিখে, আমরা নির্দেশাবলী এবং ঘোষণাপত্রের পাশাপাশি ত্রুটি-প্রবণ এডিএল এড়াতে চাই।

এটি একটি ব্যঙ্গাত্মক উত্তর হতে বোঝানো হয়েছে। :-D

আমি এটিতে গুগলের মাধ্যমে হার্ব সটারের সাথে আছি। সি ++ কোডিং স্ট্যান্ডার্ডগুলি থেকে:

আপনি করতে পারেন উচিত ঘোষণা ব্যবহার নামস্থান ব্যবহার ও নির্দেশে #include নির্দেশনা এবং এটি সম্পর্কে Feel Good পরে আপনার বাস্তবায়ন ফাইলের মধ্যে অকুণ্ঠচিত্তে। এর বিপরীতে বারবার বলা সত্ত্বেও, ঘোষণা এবং নির্দেশাবলী ব্যবহার করে নেমস্পেস খারাপ নয় এবং তারা নেমস্পেসের উদ্দেশ্যকে পরাভূত করে না। বরং, তারা হ'ল নেমস্পেসকে ব্যবহারযোগ্য করে তোলে ।

আপনি সম্ভাব্য নেমস্পেস দ্বন্দ্বগুলি সম্পর্কে অবলম্বন করতে পারেন যা সম্ভবত কখনই প্রকাশিত হয় না এবং সম্ভবত এজাতীয় জ্যোতির্বিজ্ঞানের বিরল ইভেন্টে সাবধানতার সাথে usingনির্দেশাবলী এড়িয়ে এবং আপনি যে প্রতিটি জিনিস (অপারেটরদের কাছে) usingঘোষণার সাথে ব্যবহার করেন তা স্পষ্ট করে নির্দিষ্ট করে বা এজাতীয় জ্যোতির্বিজ্ঞানের বিরল ইভেন্টে সংশোধন করা কঠিন হবে না বা শুধু এগিয়ে যান এবং শুরু করুন using namespace std। আমি পরবর্তীটির উত্পাদনশীলতার দিক থেকে প্রস্তাব দিই।

বেশিরভাগ সি ++ পাঠ্য পুস্তক নেমস্পেস স্ট্যান্ড ব্যবহার করে নতুনদের শিখায়; তারা কি খারাপ কোডিং অনুশীলন প্রচার করছে?

বিপরীত যদি আপনি আমাকে জিজ্ঞাসা করেন, এবং আমি বিশ্বাস করি উপরের স্যটারের সাথে একমত হয়।

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

এটি বলেছিল, হেডার ফাইলগুলিতে নির্দেশনা এবং ঘোষণা উভয়ই এড়িয়ে চলুন using। এটা ঠিক প্লেড ডিপার্ড। তবে উত্স ফাইলগুলির জন্য, এবং বিশেষত যেগুলির পুরো পৃষ্ঠাটি #includeনির্দেশাবলীতে ভরাট নেই , আমি বলব আপনি যদি গুগলের পক্ষে কাজ না করেন তবে এটি ঘামবেন না।

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