আমি সিপিপি ফাইলগুলি অন্তর্ভুক্ত করব না এবং এর পরিবর্তে শিরোনামটি ব্যবহার করব না কেন?


147

তাই আমি আমার প্রথম সি ++ প্রোগ্রামিংয়ের কাজ শেষ করে আমার গ্রেড পেয়েছি। তবে গ্রেডিং অনুসারে, আমি এর জন্য চিহ্নগুলি হারিয়েছি including cpp files instead of compiling and linking them। আমি এর অর্থ সম্পর্কে খুব বেশি পরিষ্কার নই।

আমার কোডটি একবার দেখে, আমি আমার ক্লাসগুলির জন্য শিরোনাম ফাইলগুলি তৈরি না করা বেছে নিয়েছি, তবে সিপিপি ফাইলগুলিতে সমস্ত কিছুই করেছি (এটি শিরোনামের ফাইলগুলি ব্যতীত দুর্দান্ত কাজ করে বলে মনে হয়েছিল ...)। আমি অনুমান করছি যে গ্রেডারের অর্থ হ'ল আমি "# অন্তর্ভুক্ত" মাইকিপিফিলিপিপি "; ' আমার কিছু ফাইলের মধ্যে

#includeসিপিপি ফাইলগুলিকে আইএন করার জন্য আমার যুক্তিটি ছিল: - শিরোনাম ফাইলটিতে যা হওয়ার কথা ছিল তা আমার সিপিপি ফাইলে ছিল, তাই আমি ভান করেছিলাম এটি একটি শিরোনাম ফাইলের মতো ছিল - বানর-দেখুন-বানরের মতো ফ্যাশন, আমি দেখলাম যে অন্যটি হেডার ফাইলগুলি ফাইলগুলিতে ছিল #include, তাই আমি আমার সিপিপি ফাইলের জন্যও তাই করেছি।

তাহলে আমি ঠিক কী ভুল করেছি এবং কেন এটি খারাপ?


36
এই সত্যিই একটি ভাল প্রশ্ন। আমি আশা করি এর মাধ্যমে প্রচুর সি ++ নতুন পাওয়া যাবে।
মিয়া ক্লার্ক

উত্তর:


174

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

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

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

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

"ওহ না! ভয়ঙ্কর লাগছে! তবে আমি কি এই মারাত্মক পরিণতি রোধ করতে পারি ?!" দুর্ভাগ্যক্রমে, আপনি এটি করতে পারে এমন খুব বেশি কিছু নেই। এটি সংকলন করতে যদি ঘন্টা সময় নেয় তবে এটি সংকলন করতে কয়েক ঘন্টা সময় নেয়। তবে এটি কেবল প্রথমবারের জন্যই গুরুত্বপূর্ণ - একবার আপনি এটি একবার সংকলন করলে, এটি আবার সংকলনের কোনও কারণ নেই।

কিছু না বদলে

এখন, যদি আপনার কাছে দুই মিলিয়ন লাইন কোড এক সাথে এক বিশাল আকারের বেহামথের সাথে একত্রীভূত হয় এবং একটি সরল বাগ ফিক্স করা দরকার যেমন, বলুন, এর x = y + 1অর্থ এটি পরীক্ষা করার জন্য আপনাকে সমস্ত দুই মিলিয়ন লাইন আবার সংকলন করতে হবে। এবং যদি আপনি এটির x = y - 1পরিবর্তে কোনও কাজটি করতে চেয়েছিলেন তা খুঁজে বের করে, তবে আবারও, দুই মিলিয়ন লাইনের সংকলন আপনার জন্য অপেক্ষা করছে। এটি বেশ কয়েক ঘন্টা সময় নষ্ট করে যা আরও ভাল কিছু করতে ব্যয় করা যেতে পারে।

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

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

হুম। আপনি সেখানে কিছু হতে পারে। যে আপনার জন্য কাজ কিভাবে আমাকে জানি।


13
ভাল উত্তর, স্যার। এটি মজাদার ছিল, এবং সহজেই বোঝা যায়। আমি চাই আমার পাঠ্যপুস্তকটি এভাবে লেখা হত।
ialm

@ ওয়েওল শিরোনামের জন্য বইয়ের প্রথম সিরিজ অনুসন্ধান করুন - যদিও তাদের কোনও সি ++ সংস্করণ রয়েছে তা আমি জানি না। headfirstlabs.com
Amarghosh

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

অবশ্যই এটি সমস্ত টেম্পলেটগুলির জন্য পৃথক হয়ে যায় কারণ বেশিরভাগ সংকলক 'এক্সপোর্ট' কীওয়ার্ড সমর্থন / প্রয়োগ করে না।
কিটসুনওয়াইএমজি

1
আর একটি বিষয় হ'ল আপনারकडे অনেকগুলি আর্ট লাইব্রেরি রয়েছে (যদি বুস্টের কথা ভাবেন) যা কেবল শিরোনামের ক্লাস ব্যবহার করে ... হ্যাঁ, অপেক্ষা করুন? অভিজ্ঞ প্রোগ্রামার বাস্তবায়ন থেকে ইন্টারফেসকে আলাদা করে না কেন? উত্তরের অংশটি অন্ধভাবে বলেছিল যা হতে পারে, অন্য অংশ হতে পারে একটি ফাইল যখন সম্ভব হয় তখন তার চেয়ে দুটি ভাল হয় এবং অন্য অংশটি হ'ল লিঙ্কিংয়ের ব্যয় অনেক বেশি হতে পারে। উত্সের সরাসরি অন্তর্ভুক্তি এবং সংযোজকটি অপ্টিমাইজ করে আমি দশগুণ দ্রুত প্রোগ্রামগুলি দেখেছি। কারণ লিঙ্কিং বেশিরভাগই অপ্টিমাইজেশনকে ব্লক করে।
ক্রিসস

45

আপনি চেয়েছিলেন এটি সম্ভবত আরও বিশদ উত্তর, তবে আমি মনে করি একটি শালীন ব্যাখ্যা ন্যায়সঙ্গত।

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

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

/* Function declaration, usually found in headers. */
/* Implicitly 'extern', i.e the symbol is visible everywhere, not just locally.*/
int add(int, int);

/* function body, or function definition. */
int add(int a, int b) 
{
   return a + b;
}

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

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

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

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

দুটি ব্যাতিক্রমের জন্য, কিছু লোকেরা .cpp ফাইলগুলিতে ইনলাইন ফাংশন, টেম্পলেটড ফাংশন এবং টেম্পলেটযুক্ত প্রকারের প্রয়োগগুলি এবং "ccp ফাইল অন্তর্ভুক্ত করার জন্য" ভাল "বলে মনে করেন। এটি শিরোনাম বা উত্স ফাইল সত্যই গুরুত্বপূর্ণ নয়; প্রিপ্রোসেসর যত্ন করে না এবং এটি কেবল একটি সম্মেলন।

সি ++ কোড (বেশ কয়েকটি ফাইল) থেকে সম্পূর্ণ প্রক্রিয়াটির একটি দ্রুত সংক্ষিপ্তসার এবং একটি চূড়ান্ত কার্যকর কার্যকর:

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

আবার, এটি আপনি চেয়েছিলেন তার চেয়ে স্পষ্টতই বেশি, তবে আমি আশা করি যে কৌতুকপূর্ণ-কৌতুকপূর্ণ বিবরণ আপনাকে আরও বড় ছবি দেখতে সহায়তা করবে।


2
আপনার পুরো ব্যাখ্যা জন্য আপনাকে ধন্যবাদ। আমি স্বীকার করি, এগুলি এখনও আমার কাছে বোধগম্য নয় এবং আমি মনে করি আপনার উত্তরটি আবার পড়তে হবে (এবং আবারও)।
ialm

1
একটি দুর্দান্ত ব্যাখ্যার জন্য +1। খুব খারাপ এটি সম্ভবত সমস্ত সি ++ newbies এড়াতে হবে। :)
সোনার সিউডো

1
হেই, খারাপ ঘোমটা লাগবে না। স্ট্যাক ওভারফ্লোতে, দীর্ঘতম উত্তর খুব কমই সেরা উত্তর।

int add(int, int);একটি ফাংশন ঘোষণা । এর প্রোটোটাইপ অংশটি ঠিক int, int। যাইহোক, সি ++ এর সমস্ত ফাংশনের একটি প্রোটোটাইপ রয়েছে, সুতরাং শব্দটি সত্যিকার অর্থে সি তে বোঝা যায় আমি এই উত্তরটির জন্য আপনার উত্তর সম্পাদনা করেছি।
মেলপোমেন

export2011 সালে টেমপ্লেটগুলি ভাষা থেকে সরানো হয়েছে comp এটি কখনও কখনও কম্পাইলার দ্বারা সমর্থিত হয়নি।
মেলপোমেন

10

সাধারণ সমাধানটি হ'ল .hঘোষণার .cppজন্য ফাইল এবং প্রয়োগের জন্য ফাইল ব্যবহার করা। আপনার যদি পুনরায় প্রয়োগকরণের পুনরায় ব্যবহারের প্রয়োজন হয় তবে আপনি সংশ্লিষ্ট .hফাইলটি সেই .cppফাইলটিতে অন্তর্ভুক্ত করুন যেখানে প্রয়োজনীয় শ্রেণি / ফাংশন / যা কিছু ব্যবহৃত হয় এবং ইতিমধ্যে সংকলিত .cppফাইলের সাথে লিঙ্ক করে (হয় কোনও .objফাইল - সাধারণত একটি প্রকল্পের মধ্যে ব্যবহার করা হয় - বা .lib ফাইল - সাধারণত ব্যবহৃত হয়) একাধিক প্রকল্প থেকে পুনঃব্যবহারের জন্য)। কেবলমাত্র বাস্তবায়ন পরিবর্তন হলে আপনার সবকিছু পুনরায় সংকলনের প্রয়োজন হবে না।


6

সিপিপি ফাইলগুলিকে একটি ব্ল্যাক বক্স হিসাবে এবং h এইচ ফাইলগুলি কীভাবে এই কালো বাক্সগুলি ব্যবহার করতে হয় তার গাইড হিসাবে ভাবেন।

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

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

এটি পড়ুন: শিরোনাম ফাইল অন্তর্ভুক্ত প্যাটার্নগুলি


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

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

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

6

শিরোনাম ফাইলগুলিতে সাধারণত ফাংশন / ক্লাসের ঘোষণা থাকে, যখন .cpp ফাইলগুলিতে প্রকৃত বাস্তবায়ন থাকে। সংকলনের সময়, প্রতিটি .cpp ফাইল একটি অবজেক্ট ফাইলে (সাধারণত এক্সটেনশন .o) সংকলিত হয় এবং লিঙ্কার বিভিন্ন অবজেক্ট ফাইলগুলিকে চূড়ান্ত নির্বাহের সাথে সংযুক্ত করে। সংযোগ প্রক্রিয়াটি সাধারণত সংকলনের চেয়ে অনেক দ্রুত।

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

অসুবিধাগুলি: প্রদত্ত .cpp ফাইল সংকলন করার সময়, সংকলক অন্যান্য .cpp ফাইলগুলির মধ্যে যা দেখতে পারে তা 'দেখতে পারে না'। সুতরাং এটি কীভাবে কার্যকারিতা বাস্তবায়িত হয় তা জানে না এবং ফলস্বরূপ আগ্রাসীভাবে অনুকূলিত করতে পারে না। তবে আমি মনে করি যে আপনাকে এখনও নিজেকে নিয়ে উদ্বিগ্ন হওয়ার দরকার নেই (:


5

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


3

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

সংকলনটি আরও বেশি সময় লাগবে (এটি বৃহত প্রকল্পগুলির ক্ষেত্রে সমস্যা হয়ে দাঁড়ায়), আপনি যদি # অন্তর্ভুক্ত সিপিপি ফাইলগুলিতে সম্পাদনা করেন, তবে যে কোনও ফাইল পুনরায় সংকলনকে বাধ্য করে # এটি অন্তর্ভুক্ত করে।

কেবলমাত্র আপনার ঘোষণাগুলি শিরোনাম ফাইলগুলিতে রাখুন এবং সেগুলি অন্তর্ভুক্ত করুন (তারা আসলে প্রতি সেড কোড তৈরি করে না) এবং লিঙ্কারটি সম্পর্কিত সিপিপি কোড (যা কেবলমাত্র একবারেই সংকলিত হয়ে যায়) সহ ঘোষণাগুলি সরিয়ে দেবে।


সুতরাং, দীর্ঘ সময় সংকলনের সময়টি ছাড়াও, আমি যখন আমার সিপিপি ফাইলকে অন্তর্ভুক্ত সিপিপি ফাইলগুলিতে ফাংশনগুলি ব্যবহার করে প্রচুর বিভিন্ন ফাইলে অন্তর্ভুক্ত করি তখন আমার সমস্যা হতে শুরু করে?
ialm

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

2

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

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


2

পুনরায় ব্যবহারযোগ্যতা, আর্কিটেকচার এবং ডেটা এনক্যাপসুলেশন

এখানে একটি উদাহরণ:

বলুন যে আপনি একটি সিপিপি ফাইল তৈরি করেছেন যা একটি ক্লাস মাইস্ট্রিংয়ের স্ট্রিং রুটিনগুলির একটি সাধারণ ফর্ম ধারণ করে, আপনি এর জন্য ক্লাস ডেসালটি একটি মাইস্ট্রিংয়ের মধ্যে রাখেন। mystring.cpp কে একটি .obj ফাইলে সংকলন করে

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

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

পরে যদি আপনার আরও আরও .obj ফাইল থাকে তবে আপনি সেগুলি একটি .lib ফাইলের সাথে সংযুক্ত করতে পারেন এবং পরিবর্তে তার সাথে লিঙ্ক করতে পারেন।

আপনি mystring.cpp ফাইল পরিবর্তন করতে এবং আরও কার্যকরভাবে এটি প্রয়োগ করার সিদ্ধান্ত নিতে পারেন, এটি আপনার মেইন সিপিপি বা আপনার বন্ধুরা প্রোগ্রামকে প্রভাবিত করবে না।


2

যদি এটি আপনার পক্ষে কাজ করে তবে এতে কোনও ভুল নেই - কেবলমাত্র এটি এমন লোকদের পালকগুলিকে কাঁপিয়ে দেবে যাঁরা মনে করেন যে কাজগুলি করার একমাত্র উপায় আছে।

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

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

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

আপনি যা করেছেন তার সম্পর্কে সত্যই "অপ্রচলিত" হ'ল আপনার অন্তর্ভুক্ত ফাইলগুলিকে ".h" বা ".hpp" এর পরিবর্তে ".cpp" নামকরণ করা।


1

আপনি যখন কোনও প্রোগ্রাম সংকলন এবং লিঙ্ক করেন তখন সংকলক প্রথমে পৃথক সিপিপি ফাইলগুলি সংকলন করে এবং তারপরে সেগুলি লিঙ্ক করে (সংযুক্ত) হয়। শিরোনামগুলি কখনই সংকলিত হবে না, যদি না প্রথমে সিপিপি ফাইলে অন্তর্ভুক্ত থাকে।

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


আপনি যদি শিরোলেখ ফাইলটির বাইরে থাকা বাস্তবায়নটি ছেড়ে দেন তবে আমাকে ক্ষমা করবেন তবে এটাই ঠিক আমার কাছে জাভা ইন্টারফেসের মতো মনে হচ্ছে?
গানসুব

1

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

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

আমি এখনও আপনার মত শিখছি :)


বইয়ের পরামর্শের জন্য ধন্যবাদ। আমি জানি না যে আমি কখনও বড় আকারের সি ++ প্রোগ্রাম তৈরির পর্যায়ে
পৌঁছব কিনা

বড় মাপের প্রোগ্রামগুলি কোড করা এবং অনেক চ্যালেঞ্জের জন্য এটি মজাদার। আমি এটি পছন্দ করতে শুরু করছি :)
পঙ্কজট

1

এটি কোনও বই লেখার মতো, আপনি একবারে সমাপ্ত অধ্যায়গুলি মুদ্রণ করতে চান

বলুন আপনি একটি বই লিখছেন। আপনি যদি অধ্যায়গুলি পৃথক ফাইলে রাখেন তবে আপনাকে কেবলমাত্র একটি অধ্যায় মুদ্রণ করতে হবে যদি আপনি এটি পরিবর্তন করে থাকেন। একটি অধ্যায় নিয়ে কাজ করা অন্য কোনওটিরও পরিবর্তন হয় না।

তবে সিপিপি ফাইলগুলি সহ কম্পাইলারের দৃষ্টিকোণ থেকে বইটির সমস্ত অধ্যায়গুলি একটি ফাইলে সম্পাদনা করার মতো। তারপরে আপনি যদি এটি পরিবর্তন করেন তবে আপনার সংশোধিত অধ্যায়টি মুদ্রণ করতে আপনাকে পুরো বইয়ের সমস্ত পৃষ্ঠা মুদ্রণ করতে হবে। অবজেক্ট কোড জেনারেশনে কোনও "নির্বাচিত পৃষ্ঠাগুলি মুদ্রণ করুন" বিকল্প নেই।

সফ্টওয়্যারটিতে ফিরুন: আমার কাছে লিনাক্স এবং রুবি এসসিআর পড়ে আছে। কোডের লাইনগুলির মোটামুটি পরিমাপ ...

     Linux       Ruby
   100,000    100,000   core functionality (just kernel/*, ruby top level dir)
10,000,000    200,000   everything 

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

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