এটি পৃথক সংকলনের প্রয়োজনীয়তার কারণেই এবং টেমপ্লেটগুলি ইনস্ট্যান্টেশন-স্টাইলের বহুবচন রয়েছে।
একটি ব্যাখ্যার জন্য কংক্রিটের আরও কাছে যেতে দিন। বলুন আমি নীচের ফাইলগুলি পেয়েছি:
- foo.h
- এর ইন্টারফেস ঘোষণা করে
class MyClass<T>
- foo.cpp
- বাস্তবায়ন সংজ্ঞায়িত
class MyClass<T>
- bar.cpp
পৃথক সংকলন অর্থ আমি কম্পাইল করতে সক্ষম হওয়া উচিত foo.cpp থেকে স্বাধীনভাবে bar.cpp । সংকলক প্রতিটি সংকলন ইউনিটে সম্পূর্ণ স্বতন্ত্রভাবে বিশ্লেষণ, অপ্টিমাইজেশন এবং কোড জেনারেশনের সমস্ত কঠোর পরিশ্রম করে; আমাদের পুরো প্রোগ্রাম বিশ্লেষণ করার দরকার নেই। এটি কেবলমাত্র লিঙ্কার যা একবারে পুরো প্রোগ্রামটি পরিচালনা করতে হবে এবং লিঙ্কারের কাজটি যথেষ্ট সহজ।
bar.cpp এমনকি অস্তিত্ব যখন আমি কম্পাইল দরকার নেই foo.cpp , কিন্তু আমি এখনও লিঙ্ক করতে সক্ষম হওয়া উচিত foo.o আমি ইতিমধ্যে সঙ্গে একসঙ্গে ছিল bar.o পুনরায় কম্পাইল করতে ছাড়াই, আমি কেবল মাত্র উত্পাদিত করেছি foo বিন্যাস .cpp । foo.cpp এমনকি ডায়নামিক লাইব্রেরিতে সংকলিত হতে পারে, foo.cpp ছাড়াই অন্য কোথাও বিতরণ করা যায় এবং আমি foo.cpp লেখার কয়েক বছর পরে তারা কোডের সাথে লিঙ্কযুক্ত ।
"ইনস্ট্যান্টেশন-স্টাইল পলিমারফিজম" এর অর্থ হল যে টেমপ্লেটটি MyClass<T>
আসলে একটি জেনেরিক শ্রেণি নয় যা কোনও কোডের সাথে সংকলিত হতে পারে যা কোনও মূল্যের জন্য কাজ করতে পারে T
। যে বক্সিং যেমন ওভারহেড যেমন যোগ হবে, allocators এবং কন্সট্রাকটর, ইত্যাদি সি ++ টেমপ্লেট উদ্দেশ্য লিখতে থাকার এড়াতে হয় ফাংশন পয়েন্টার পাস প্রয়োজন মতো প্রায় একই class MyClass_int
, class MyClass_float
ইত্যাদি, কিন্তু এখনও কম্পাইল কোড যে সঙ্গে শেষ পাবে বেশিরভাগ যেন আমরা ছিল প্রত্যেকটি সংস্করণ আলাদাভাবে লিখিত। সুতরাং একটি টেমপ্লেট আক্ষরিকভাবে একটি টেম্পলেট; একটি বর্গ টেমপ্লেট না , একটি বর্গ প্রতিটি জন্য একটি নতুন শ্রেণী তৈরি করার জন্য একটি রেসিপি T
আমরা এনকাউন্টার। কোনও টেম্পলেট কোডে সংকলন করা যায় না, কেবলমাত্র টেমপ্লেট ইনস্ট্যান্ট করার ফলাফল সংকলন করা যায়।
সুতরাং যখন foo.cpp সংকলিত হয়, তখন সংকলকটি বার.cpp দেখতে পাবে না যে MyClass<int>
এটি প্রয়োজনীয়। এটি টেমপ্লেটটি দেখতে পারে MyClass<T>
, তবে এটি এর জন্য কোড নির্গত করতে পারে না (এটি একটি টেম্পলেট, কোনও শ্রেণি নয়)। এবং বার. cpp সংকলিত হয়ে গেলে, সংকলকটি দেখতে পারে যে এটির একটি তৈরি করা দরকার MyClass<int>
তবে এটি টেমপ্লেটটি দেখতে পাবে না MyClass<T>
(কেবলমাত্র তার ইন্টারফেসটি foo.h এ ) যাতে এটি তৈরি করতে পারে না।
যদি foo.cpp নিজেই ব্যবহার করে MyClass<int>
তবে তার জন্য কোডটি foo.cpp সংকলনের সময় উত্পন্ন হবে , সুতরাং যখন বার.ও foo.o এর সাথে যুক্ত হবে তখন সেগুলি আপ করা যাবে এবং কাজ করবে। আমরা একটি বাস্তব টেমপ্লেট লিখে .cpp ফাইলে টেমপ্লেট ইনস্ট্যান্টেশনের একটি সীমাবদ্ধ সেটটি মঞ্জুর করার জন্য সেই বাস্তবতাকে ব্যবহার করতে পারি। তবে বার কোড পিপিপির পক্ষে এই টেম্পলেটটিকে একটি টেম্পলেট হিসাবে ব্যবহার করার এবং এটি যে ধরণের পছন্দ তা পছন্দ করে তা ইনস্ট্যান্ট করার কোনও উপায় নেই ; এটি কেবলমাত্র টেম্পলেটেড শ্রেণীর পূর্ব-বিদ্যমান সংস্করণগুলি ব্যবহার করতে পারে যা foo.cpp এর লেখক ভেবেছিলেন।
আপনি ভাবতে পারেন যে কোনও টেমপ্লেট সংকলন করার সময় সংকলকটির "সমস্ত সংস্করণ উত্পন্ন করা উচিত" এর সাথে লিঙ্ক চলাকালীন কখনই ফিল্টার আউট ব্যবহার করা হয় না। বিশাল ওভারহেড এবং চূড়ান্ত অসুবিধাগুলি বাদ দিয়ে এ জাতীয় পদ্ধতির মুখোমুখি হতে হবে কারণ পয়েন্টার এবং অ্যারেগুলির মতো "টাইপ মডিফায়ার" বৈশিষ্ট্যগুলি কেবল বিল্ট-ইন টাইপগুলিকেও অসীম ধরণের সংখ্যার জন্ম দেয়, যখন আমি এখন আমার প্রোগ্রামটি প্রসারিত করি তখন কী হয়? যোগ করে:
- baz.cpp
- ঘোষণা এবং প্রয়োগ
class BazPrivate
, এবং ব্যবহারMyClass<BazPrivate>
এটির কোনও সম্ভাব্য উপায় নেই যে আমরা না হলে এটি কাজ করতে পারে
- প্রোগ্রামে যখনই আমরা কোনও নতুন ফাইল পরিবর্তন করি তখন প্রতিবার foo.cpp কে পুনরায় সংকলন করতে হয় , যদি এটির মধ্যে একটি নতুন উপন্যাস ইনস্ট্যান্টেশন যুক্ত হয়
MyClass<T>
- আবশ্যক যে baz.cpp এর সম্পূর্ণ টেমপ্লেট (সম্ভবত শিরোনামের মাধ্যমে অন্তর্ভুক্ত) রয়েছে
MyClass<T>
, যাতে সংকলক baz.cppMyClass<BazPrivate>
সংকলনের সময় উত্পন্ন করতে পারে ।
কারও পছন্দ হয় না (1), কারণ পুরো প্রোগ্রাম-বিশ্লেষণ সংকলন সিস্টেমগুলি চিরতরে সংকলনের জন্য নেয় এবং কারণ সোর্স কোড ব্যতীত সংকলিত গ্রন্থাগারগুলি বিতরণ করা অসম্ভব হয়ে পড়ে। সুতরাং আমাদের পরিবর্তে (2) আছে।