সি ++ হেডারে "নেমস্পেস ব্যবহার করা"


119

আমাদের সমস্ত সি ++ কোর্সে সমস্ত শিক্ষক তাদের ফাইলগুলিতে সর্বদা using namespace std;ডানদিকে রাখেন । তখন থেকে এটি আমার পক্ষে বিপজ্জনক বলে মনে হচ্ছে সেই শিরোলেখটিকে অন্য একটি প্রোগ্রামে অন্তর্ভুক্ত করে আমি নামটি আমার প্রোগ্রামে আমদানি করব, সম্ভবত এটি উপলব্ধি করা, উদ্দেশ্য না করে বা এটি না করেই (শিরোনাম অন্তর্ভুক্তি খুব গভীরভাবে বাসা বাঁধতে পারে)।#include.h

সুতরাং আমার প্রশ্নটি দ্বিগুণ: আমি কি ঠিক বলছি যা using namespaceহেডার ফাইলগুলিতে ব্যবহার করা উচিত নয়, এবং / অথবা এটিকে পূর্বাবস্থায় ফেলার কোনও উপায় আছে, যেমন:

//header.h
using namespace std {
.
.
.
}

একই লাইন বরাবর আরও একটি প্রশ্ন: একটি শিরোলেখটি #includeসমস্ত শিরোলেখ যা .cppফাইলের সাথে সম্পর্কিত এটি ফাইল করে, যা কেবলমাত্র শিরোনাম সংজ্ঞাগুলির জন্য প্রয়োজনীয় এবং সেই .cppফাইলটি #includeবাকী, বা কিছুই না করে এবং যা যা প্রয়োজন তা ঘোষণা করে extern?
প্রশ্নের পিছনে যুক্তি উপরের মত একই: .hফাইলগুলি অন্তর্ভুক্ত করার সময় আমি আশ্চর্য হতে চাই না ।

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

ধন্যবাদ.



3
পার্শ্ব নোট হিসাবে, যদি আপনি using namespaceবিবৃতিগুলির কারণে নামের সংঘর্ষগুলি পান তবে আপনি সমস্যার সমাধানের জন্য পুরোপুরি যোগ্যতাসম্পন্ন নামটি ব্যবহার করতে পারেন।
মারিয়াস বানসিলা

উত্তর:


115

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

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

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


2
আমরা কি usingআমাদের .cppফাইলগুলিতে স্টেটমেন্ট ব্যবহার করতে পারি ? 3rdPartyLib::BigClassName<3rdPartyLib::AnotherBigName,3rdPartyLib::AnotherBigName>::Iteratorগুলি নখদর্পণে মৃত্যু হয়।
ক্রিস্টোফার

1
এবং আমাদের templateফাংশনগুলি কীভাবে প্রবাহিত করা উচিত - যা শিরোনামগুলিতে থাকা উচিত? typedefs?
ক্রিস্টোফার

1
@ ডনলান, মনে হচ্ছে আপনি বেশ কিছুক্ষণ সাড়া পেলেন না ... হ্যাঁ, আপনি খুব উদ্বেগ ছাড়াই ফাইলের usingমধ্যে বিবৃতি ব্যবহার করতে পারেন .cppকারণ সুযোগটি কেবলমাত্র সেই ফাইলটিতে সীমাবদ্ধ থাকবে তবে কোনও #includeবিবৃতি দেওয়ার আগে কখনও তা করবেন না do শিরোনামগুলিতে সংজ্ঞায়িত টেম্পলেট ফাংশন হিসাবে, দুর্ভাগ্যক্রমে আমি কেবল নামস্থানটি লেখার চেয়ে ভাল কোনও সমাধানের কথা জানি না ... সম্ভবত আপনি usingএকটি পৃথক স্কোপের মধ্যে কোনও ঘোষণা দিতে পারেন { /* using statement in between brackets */ }, এটি কমপক্ষে এটি বর্তমান ফাইলটি থেকে বাঁচতে বাধা দিতে পারে ।
tjwrona1992

26

সুটার এবং আলেকজান্দ্রেস্কুর আইটেম 59 "সি ++ কোডিং স্ট্যান্ডার্ড: 101 বিধি, নির্দেশিকা এবং সেরা অভ্যাস" :

59. একটি শিরোনাম ফাইলে বা একটি # অন্তর্ভুক্ত করার আগে নেমস্পেস ইউজিং লিখবেন না।

নেমস্পেস usingগুলি আপনার সুবিধার জন্য, অন্যের উপর চাপ দেওয়ার জন্য নয়: usingকোনও usingনির্দেশের আগে কোনও ঘোষণা বা নির্দেশ কখনই লিখবেন না #include

প্রত্নতাত্ত্বিক: শিরোনাম ফাইলগুলিতে, নাম স্থান স্তরের usingনির্দেশনা বা usingঘোষণা লিখবেন না ; পরিবর্তে, সমস্ত নাম স্পষ্টতই নেমস্পেস-যোগ্যতা অর্জন করুন।

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

একটি using ঘোষণা একটি বন্ধুকে নিয়ে আসে। একটি using নির্দেশিকা নেমস্পেসের সমস্ত বন্ধুকে নিয়ে আসে। আপনার শিক্ষকদের ব্যবহার using namespace std;একটি ব্যবহার নির্দেশিকা।

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


12

হেডারের অভ্যন্তরে শিরোনাম অন্তর্ভুক্ত করার সময় আপনাকে সতর্ক হওয়া দরকার be বড় প্রকল্পগুলিতে এটি একটি খুব জটযুক্ত নির্ভরশীল শৃঙ্খলা তৈরি করতে পারে যা প্রকৃতপক্ষে প্রয়োজনীয়গুলির চেয়ে বড় / দীর্ঘ পুনর্নির্মাণগুলিকে ট্রিগার করে। সি ++ প্রকল্পগুলিতে ভাল শারীরিক কাঠামোর গুরুত্ব সম্পর্কে আরও জানতে এই নিবন্ধটি এবং এর ফলোআপটি দেখুন।

একেবারে যখন প্রয়োজন হয় তখন আপনার কেবলমাত্র শিরোনামের ভিতরে শিরোনাম অন্তর্ভুক্ত করা উচিত (যখনই কোনও শ্রেণীর পূর্ণ সংজ্ঞা প্রয়োজন হয়) এবং আপনি যেখানেই পারেন (যখন শ্রেণির প্রয়োজন হয় তখন পয়েন্টার বা একটি রেফারেন্স হয়) forward

নেমস্পেসের ক্ষেত্রে, আমি আমার শিরোনাম ফাইলগুলিতে সুস্পষ্ট নেমস্পেস স্কোপিং ব্যবহার করতে ঝোঁক, এবং কেবলমাত্র using namespaceআমার সিপিপি ফাইলগুলিতে রেখেছি।


1
কীভাবে আপনি templateকার্য ঘোষণাকে স্ট্রিমলাইন করবেন ? যে হেডারে ঘটতে হবে, না?
ক্রিস্টোফার

6

গড্ডার্ড স্পেস ফ্লাইট সেন্টার কোডিং মানগুলি (সি এবং সি ++ এর জন্য) দেখুন। এটি আগের তুলনায় কিছুটা শক্ত হয়ে দাঁড়ায় - এসও প্রশ্নগুলির আপডেট উত্তরগুলি দেখুন:

জিএসএফসি সি ++ কোডিং মান বলে:

.33.3.7 #includeব্যবহারকারীদের #includeপ্রয়োজনীয় ফাইলগুলিতে বাধ্য করার পরিবর্তে প্রতিটি শিরোলেখ ফাইলটি সংকলনের প্রয়োজন ফাইলগুলি needs #includesশিরোনামের প্রয়োজন অনুসারে সীমাবদ্ধ থাকবে; অন্যান্য #includesউত্স ফাইলে রাখা উচিত।

ক্রস-রেফারেন্সযুক্ত প্রথম প্রশ্নের মধ্যে এখন জিএসএফসি সি কোডিং স্ট্যান্ডার্ডের একটি উদ্ধৃতি এবং যুক্তি অন্তর্ভুক্ত রয়েছে তবে পদার্থটি একইরকম হয়।


5

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

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


4

তুমি ঠিক. এবং যে কোনও ফাইলের মধ্যে কেবলমাত্র সেই ফাইলটির জন্য প্রয়োজনীয় শিরোনাম অন্তর্ভুক্ত করা উচিত। যেমন "বাস্তব বিশ্বের প্রকল্পগুলিতে কি ভুল কিছু করা হয়?" - হ্যাঁ!


4

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

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

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


4

"[[ usingঘোষণা]] কে পূর্বাবস্থায় ফেলার কোনও উপায় আছে কি ?"

আমি মনে করি যে usingঘোষণাগুলি সুযোগ দ্বারা প্রভাবিত হয়েছে তা উল্লেখ করা দরকারী useful

#include <vector>

{   // begin a new scope with {
    using namespace std;
    vector myVector;  // std::vector is used
}   // end the scope with }

vector myOtherVector;   // error vector undefined
std::vector mySTDVector // no error std::vector is fully qualified

তাই কার্যকরভাবে হ্যাঁ। usingঘোষণার পরিধি সীমাবদ্ধ করে এর প্রভাব কেবল সেই সুযোগের মধ্যেই থাকে; যখন সেই সুযোগটি শেষ হয় তখন এটি 'পূর্বাবস্থায় ফিরে আসে'।

যখন usingঘোষণাটি অন্য কোনও স্কোপের বাইরে কোনও ফাইলে ঘোষণা করা হয় তখন এতে ফাইল-সুযোগ রয়েছে এবং সেই ফাইলের সমস্ত কিছুকে প্রভাবিত করে।

শিরোনামের ফাইলের ক্ষেত্রে, যদি usingঘোষণাপত্রটি ফাইল-স্কোপে থাকে তবে এটি শিরোনামের অন্তর্ভুক্ত থাকা কোনও ফাইলের পরিধি পর্যন্ত প্রসারিত হবে।


2
আপনি একমাত্র প্রকৃত প্রশ্নটি বুঝতে পেরেছিলেন বলে মনে হয় ... তবে আমার সংকলন ক্লাস হ্রাসের অভ্যন্তরে ব্যবহার করে আমার সম্পর্কে খুব খুশি নয়।
rustypaper

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

2

আমি বিশ্বাস করি আপনি যদি নেস্টেড নেমস্পেসে নিজের ঘোষণাটি লিখে থাকেন তবে আপনি নিরাপদে সি ++ শিরোনামগুলিতে 'ব্যবহার' করতে পারবেন:

namespace DECLARATIONS_WITH_NAMESPACES_USED_INCLUDED
{
    /*using statements*/

    namespace DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED
    {
        /*declarations*/
    }
}

using namespace DECLARATIONS_WITH_NAMESPACES_USED_INCLUDED::DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED;

এর মধ্যে কেবল নাম ঠিকানাগুলি ব্যবহার না করে 'DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED' এ ঘোষণা করা জিনিসগুলি অন্তর্ভুক্ত করা উচিত। আমি এটি মিংডব্লিউ 64 সংকলকটিতে পরীক্ষা করেছি।


এটি এমন একটি দরকারী কৌশল যা আমি আগে দেখিনি; ধন্যবাদ। সাধারণত আমি পুরো স্কোপ যোগ্যতা ব্যবহার করে এবং usingফাংশন সংজ্ঞাগুলির ভিতরে ঘোষণাপত্র রাখার ক্ষেত্রে ভাল ছিলাম যাতে তারা ফাংশনের বাইরে নেমস্পেসগুলি দূষিত না করে। তবে এখন আমি একটি শিরোনাম ফাইলে সি ++ 11 ব্যবহারকারীর সংজ্ঞায়িত আক্ষরিক ব্যবহার করতে চাই এবং সাধারণ কনভেনশন অনুযায়ী আক্ষরিক অপারেটররা একটি নামস্থান দ্বারা সুরক্ষিত থাকে; তবে আমি সেগুলি কন্সট্রাক্টর ইনিশিয়ালাইজার তালিকায় ব্যবহার করতে চাই না যেগুলি এমন কোনও সুযোগ নয় যা আমি একটি দূষণকারী usingঘোষণা ব্যবহার করতে পারি । সুতরাং এই সমস্যাটি সমাধান করার জন্য এটি দুর্দান্ত।
অ্যান্টনি হল

যদিও এই প্যাটার্ন একটি দুর্ভাগ্যজনক পার্শ্বপ্রতিক্রিয়া যে কোনো শ্রেণীর অন্তরতম নামস্থান ভিতরে ঘোষিত সম্পূর্ণরূপে যোগ্যতাসম্পন্ন নাম দিয়ে কম্পাইলার ত্রুটি বার্তা দেখানো হবে হল: error: ... DECLARATIONS_WITH_NAMESPACES_USED_INCLUDED:: DECLARATIONS_WITH_NO_NAMESPACES_USED_INCLUDED::ClassName ...। কমপক্ষে, এটি আমার জন্য জি ++ এ কী ঘটছে।
অ্যান্টনি হল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.