c++ - গঠন - হেডার ফাইল কী




কেন টেমপ্লেট শুধুমাত্র হেডার ফাইল প্রয়োগ করা যাবে? (10)

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

এক টেমপ্লেট এর সমস্ত ব্যবহারের জন্য কম্পাইলারগুলিকে আরও "স্মার্টফোনের" হতে আরও স্মার্ট করে তুলতে পারে, তবে আমি নিশ্চিত যে পুনরাবৃত্তিমূলক বা অন্য জটিল জটিল পরিস্থিতি তৈরি করা কঠিন হবে না। AFAIK, কম্পাইলার যেমন বর্ণন এগিয়ে না। এন্টন উল্লেখ করেছেন, কিছু কম্পাইলার টেমপ্লেট ইনস্টিটিউশনের স্পষ্ট রপ্তানি ঘোষণাগুলি সমর্থন করে, কিন্তু সমস্ত কম্পাইলার এটি সমর্থন করে না (এখনো?)।

সি ++ স্ট্যান্ডার্ড লাইব্রেরি থেকে উদ্ধৃতি : একটি টিউটোরিয়াল এবং হ্যান্ডবুক :

টেমপ্লেট ব্যবহার করার একমাত্র পোর্টেবল উপায় ইনলাইন ফাংশন ব্যবহার করে হেডার ফাইলগুলিতে তাদের বাস্তবায়ন করা।

কেন?

(ব্যাখ্যা: শিরোনাম ফাইল শুধুমাত্র পোর্টেবল সমাধান নয়। তবে এটি সবচেয়ে সুবিধাজনক পোর্টেবল সমাধান।)


এখানে প্রচুর সঠিক উত্তর, কিন্তু আমি এটি যোগ করতে চেয়েছিলাম (সম্পূর্ণতার জন্য):

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

সম্পাদনা: স্পষ্ট টেমপ্লেট তাত্ক্ষণিকতার উদাহরণ যোগ করা। টেমপ্লেট সংজ্ঞায়িত করা হয়েছে পরে ব্যবহৃত, এবং সব সদস্য ফাংশন সংজ্ঞায়িত করা হয়েছে।

template class vector<int>;

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

উপরের উদাহরণটি মোটামুটি নিরর্থক, কারণ ভেক্টর হেডারগুলিতে সম্পূর্ণরূপে সংজ্ঞায়িত করা হয়েছে, কেবলমাত্র একটি সাধারণ অন্তর্ভুক্ত ফাইল (পূর্বনির্ধারিত শিরোনাম?) extern template class vector<int> যাতে এটি অন্য সমস্ত (1000?) ফাইলগুলিতে তাত্ক্ষণিকভাবে রাখতে না পারে যে ভেক্টর ব্যবহার।


এটি পৃথক সংকলনের জন্য প্রয়োজনীয়তার কারণে এবং টেম্পলেটগুলি তাত্ক্ষণিক-শৈলী পলিমোফিজম।

একটি ব্যাখ্যা জন্য কংক্রিট একটু কাছাকাছি পেতে দিন। বলুন আমি নিম্নলিখিত ফাইল পেয়েছি:

  • foo.h
    • class MyClass<T> ইন্টারফেস ঘোষণা করে
  • foo.cpp
    • class MyClass<T> বাস্তবায়ন সংজ্ঞায়িত করে
  • bar.cpp
    • MyClass<int> ব্যবহার করে

পৃথক সংকলন মানে আমি bar.cpp থেকে স্বাধীনভাবে foo.cpp কম্পাইল করতে সক্ষম হওয়া উচিত। কম্পাইলার সম্পূর্ণরূপে স্বাধীনভাবে প্রতিটি সংকলন ইউনিট বিশ্লেষণ, অপ্টিমাইজেশান, এবং কোড প্রজন্মের সব হার্ড কাজ করে; আমরা পুরো প্রোগ্রাম বিশ্লেষণ করতে হবে না। এটি শুধুমাত্র লিঙ্কার যা একবারে সমগ্র প্রোগ্রাম পরিচালনা করতে হবে এবং লিঙ্কারের কাজটি বেশ সহজ।

bar.cpp এমনকি foo.cpp সংকলন করার সময়ও উপস্থিত থাকতে হবে না, তবে আমি এখনও foo.o লিঙ্ক করতে সক্ষম হব। আমি ইতিমধ্যে বারটির সাথে একসাথে ছিলাম.আমি কেবলমাত্র উত্পাদিত করেছি কেবলমাত্র foo পুনঃসংযোগ করার প্রয়োজন ছাড়া .cppfoo.cpp এমনকি একটি ডাইনামিক লাইব্রেরিতে কম্পাইল করা যেতে পারে, foo.cpp ব্যতীত অন্য কোথাও বিতরণ করা, এবং আমি foo.cpp লিখে কয়েক বছর পর কোড লিখতে পারি

"ইনস্ট্যান্টেশন-স্টাইল পলিমোরফিজম" মানে যে টেমপ্লেট MyClass<T> প্রকৃতপক্ষে জেনেরিক ক্লাস নয় যা MyClass<T> কোডের সাথে সংকলিত করা যেতে পারে যা T যেকোনো মূল্যের জন্য কাজ করতে পারে। এটি বক্সিং হিসাবে ওভারহেড যুক্ত করবে, বরাদ্দকারী এবং কনস্ট্রাক্টর ইত্যাদি ফাংশন পয়েন্টারগুলি পাস করতে হবে। C ++ টেমপ্লেটগুলির অভিপ্রায় প্রায় অভিন্ন class MyClass_int , class MyClass_float , ইত্যাদি লিখতে এড়াতে হবে তবে এখনও শেষ করতে সক্ষম হবে সংকলিত কোড যা বেশিরভাগ ক্ষেত্রে আমরা পৃথকভাবে প্রতিটি সংস্করণ লিখেছি। সুতরাং একটি টেমপ্লেট আক্ষরিক একটি টেমপ্লেট হয়; একটি ক্লাস টেমপ্লেট একটি শ্রেণী নয়, আমরা সম্মুখীন প্রতিটি T জন্য একটি নতুন বর্গ তৈরি করার জন্য এটি একটি রেসিপি। একটি টেমপ্লেট কোডে সংকলিত করা যাবে না, শুধুমাত্র টেমপ্লেটটি তাত্ক্ষণিক করার ফলাফলটি সংকলিত করা যেতে পারে।

সুতরাং যখন foo.cpp সংকলিত হয়, তখন কম্পাইলার bar.cpp দেখতে পারে না যে MyClass<int> প্রয়োজন। এটি টেমপ্লেট MyClass<T> দেখতে পারে, তবে এটির জন্য কোডটি MyClass<T> পারে না (এটি একটি টেমপ্লেট, কোনও শ্রেণী নয়)। এবং যখন bar.cpp সংকলিত হয়, কম্পাইলার দেখতে পারেন যে এটি একটি MyClass<int> তৈরি করতে হবে, তবে এটি আমার MyClass<T> (শুধুমাত্র এটির ইন্টারফেস foo.h ) দেখতে পাবে না তাই এটি তৈরি করতে পারে না এটা।

যদি foo.cpp নিজেই MyClass<int> ব্যবহার করে তবে তার জন্য কোড foo.cpp কম্পাইল করার সময় তৈরি করা হবে, তাই bar.o foo . এর সাথে সংযুক্ত থাকলেও এটি hooked up এবং কাজ করবে। আমরা একক টেমপ্লেটটি লিখে একটি। সিপিপি ফাইলটিতে টেমপ্লেট ইনস্টিটিউশনের একটি সীমাবদ্ধ সেটটিকে বাস্তবায়িত করার জন্য সেই সত্যটি ব্যবহার করতে পারি। কিন্তু টেমপ্লেটটি টেমপ্লেট হিসাবে ব্যবহার করার জন্য bar.cpp এর কোন উপায় নেই এবং এটি যেকোন ধরনের পছন্দ করে তা তাত্ক্ষণিকভাবে চালু করুন; এটি শুধুমাত্র templated শ্রেণীর প্রাক বিদ্যমান সংস্করণ ব্যবহার করতে পারেন যে foo.cpp লেখক প্রদান করা চিন্তা।

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

  • baz.cpp
    • class BazPrivate ঘোষণা করে এবং প্রয়োগ করে এবং MyClass<BazPrivate>

আমরা যদি না হয়, তাহলে এই কাজ করতে পারে যে কোন সম্ভাব্য উপায় নেই

  1. ফেইসবুক পুনরায় কম্পাইল করতে হবে যখন আমরা প্রোগ্রামটিতে যে কোনও ফাইল পরিবর্তন করবো, যদি এটি MyClass<T> এর একটি নতুন উপন্যাস তাত্ক্ষণিকতা যোগ করে,
  2. Baz.cpp এর জন্য রয়েছে (সম্ভবত হেডারের মাধ্যমে) MyClass<T> সম্পূর্ণ টেমপ্লেট, যাতে কম্পাইলার MyClass<BazPrivate> সংকলনের সময় MyClass<BazPrivate> তৈরি করতে পারে।

কেউ পছন্দ করে না (1), কারণ পুরো প্রোগ্রাম-বিশ্লেষণ সংকলন সিস্টেম কম্পাইল করার জন্য চিরতরে নেয় এবং এটি সোর্স কোড ছাড়াই সংকলিত লাইব্রেরিগুলি বিতরণ করা অসম্ভব করে তোলে। তাই আমরা পরিবর্তে আছে (2)।


এর অর্থ হল টেমপ্লেট ক্লাসগুলির পদ্ধতি বাস্তবায়নগুলি সর্বাধিক পোর্টেবল উপায় তাদের টেমপ্লেট শ্রেণির সংজ্ঞাতে সংজ্ঞায়িত করা।

template < typename ... >
class MyClass
{

    int myMethod()
    {
       // Not just declaration. Add method implementation here
    }
};

নিম্নরূপ বাস্তবায়ন পৃথক করার উপায়।

//inner_foo.h

template <typename T>
struct Foo
{
    void doSomething(T param);
};


//foo.tpp
#include "inner_foo.h"
template <typename T>
void Foo<T>::doSomething(T param)
{
    //implementation
}


//foo.h
#include <foo.tpp>

//main.cpp
#include <foo.h>

inner_foo এগিয়ে ঘোষণা আছে। foo.tpp বাস্তবায়ন আছে এবং inner_foo.h অন্তর্ভুক্ত; এবং foo.h শুধুমাত্র foo.tpp অন্তর্ভুক্ত করতে হবে, একটি লাইন আছে।

কম্পাইল সময়, foo.h এর বিষয়বস্তু foo.tpp তে অনুলিপি করা হয় এবং তারপরে পুরো ফাইলটি foo তে অনুলিপি করা হয়। এর পরে এটি কম্পাইল হয়। এই ভাবে, কোনও সীমাবদ্ধতা নেই এবং নামকরণ একটি অতিরিক্ত ফাইলের বিনিময়ে, সামঞ্জস্যপূর্ণ।

আমি এটি করি কারণ কোডের স্ট্যাটিক বিশ্লেষক যখন এটি * .tpp এর ক্লাসের অগ্রবর্তী ঘোষণাগুলি দেখতে না পান। কোন আইডিইতে কোড লেখার সময় অথবা YouCompleteMe বা অন্যদের ব্যবহার করে এটি বিরক্তিকর।


প্রকৃতপক্ষে, সি ++ 11 এর আগে মানটি export কীওয়ার্ডটিকে সংজ্ঞায়িত করে যা শিরোনাম ফাইলটিতে টেমপ্লেটগুলি ঘোষণা করা এবং অন্যত্র তাদের বাস্তবায়ন করা সম্ভব করে।

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

ফলস্বরূপ, আইএসও সি ++ স্ট্যান্ডার্ড কমিটি সি ++ 11 সহ টেমপ্লেটগুলির export বৈশিষ্ট্যগুলি সরিয়ে ফেলার সিদ্ধান্ত নিয়েছে।


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

প্রতিটি টেমপ্লেট ব্যবহারের জন্য এটির নিজস্ব শিরোনাম ফাইলটিতে টাইপডফ থাকে (UML মডেল থেকে উত্পন্ন)। তার শরীরের তাত্ক্ষণিকতা রয়েছে (যা শেষে লাইব্রেরিতে শেষ হয়)।
টেমপ্লেটের প্রতিটি ব্যবহারকারীর মধ্যে হেডার ফাইল রয়েছে এবং টাইপডফ ব্যবহার করে।

একটি পরিকল্পিত উদাহরণ:

MyTemplate.h:

#ifndef MyTemplate_h
#define MyTemplate_h 1

template <class T>
class MyTemplate
{
public:
  MyTemplate(const T& rt);
  void dump();
  T t;
};

#endif

MyTemplate.cpp:

#include "MyTemplate.h"
#include <iostream>

template <class T>
MyTemplate<T>::MyTemplate(const T& rt)
: t(rt)
{
}

template <class T>
void MyTemplate<T>::dump()
{
  cerr << t << endl;
}

MyInstantiatedTemplate.h:

#ifndef MyInstantiatedTemplate_h
#define MyInstantiatedTemplate_h 1
#include "MyTemplate.h"

typedef MyTemplate< int > MyInstantiatedTemplate;

#endif

MyInstantiatedTemplate.cpp:

#include "MyTemplate.cpp"

template class MyTemplate< int >;

main.cpp:

#include "MyInstantiatedTemplate.h"

int main()
{
  MyInstantiatedTemplate m(100);
  m.dump();
  return 0;
}

এই ভাবে শুধুমাত্র টেমপ্লেট ইনস্ট্যান্সেশনগুলিকে পুনরায় কম্পাইল করা দরকার, সমস্ত টেমপ্লেট ব্যবহারকারী (এবং নির্ভরতা) নয়।


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

একটি এক্সপোর্ট কীওয়ার্ড যা এই সমস্যাটি হ্রাস করতে অনুমিত হয় তবে এটি পোর্টেবল হওয়ার কাছাকাছি কোথাও নেই।


সংকলন পদক্ষেপের সময় আপনি একটি টেমপ্লেট ব্যবহার করার সময় কম্পাইলার প্রতিটি টেমপ্লেট তাত্ক্ষণিকতার জন্য কোড জেনারেট করবে। সংকলন এবং লিঙ্কিং প্রক্রিয়ার মধ্যে। সিপিপি ফাইলগুলিকে বিশুদ্ধ বস্তু বা মেশিন কোডে রূপান্তরিত করা হয় যার মধ্যে রেফারেন্স বা অনির্ধারিত প্রতীক রয়েছে কারণ আপনার main.cpp এ অন্তর্ভুক্ত .h ফাইলগুলি কোন বাস্তবায়ন নেই। এটি অন্য কোনও বস্তু ফাইলের সাথে সংযুক্ত হওয়ার জন্য প্রস্তুত যা আপনার টেম্পলেটের জন্য বাস্তবায়ন সংজ্ঞায়িত করে এবং এভাবে আপনার সম্পূর্ণ কার্য সম্পাদনযোগ্য। তবে যেহেতু আপনি আপনার প্রধান প্রোগ্রামে প্রতিটি টেমপ্লেট ইনস্ট্যান্টেশনের জন্য কোড তৈরি করার জন্য টেমপ্লেটগুলিকে সংকলন পদক্ষেপে প্রসেস করতে হবে, তাই লিঙ্কিং আপনাকে সাহায্য করবে না কারণ main.cpp main.o এ কম্পাইল করে এবং তারপর আপনার টেম্পলেট কম্পাইল করে। টেমপ্লেট.এতে এবং তারপর লিঙ্কিং টেমপ্লেট উদ্দেশ্য অর্জন করবে না কারণ আমি একই টেম্পলেট বাস্তবায়নে বিভিন্ন টেম্পলেট ইনস্ট্যান্সেশন লিঙ্ক করছি! এবং টেমপ্লেটগুলির বিপরীতে একটি কাজ বাস্তবায়ন করার কথা বলা হয় তবে এক শ্রেণির ব্যবহারের মাধ্যমে অনেকগুলি উপলভ্য তাত্ক্ষণের অনুমতি দেয়।

অর্থ typename T সংকলন পদক্ষেপের সময় প্রতিস্থাপিত হয়, লিঙ্কিং ধাপে নয়, তাই যদি আমি কোনও টেমপ্লেটটি কংক্রিট মান টাইপ হিসাবে প্রতিস্থাপিত না করে কোনও টেমপ্লেট সংকলন করার চেষ্টা করি তবে এটি কাজ করবে না কারণ এটি টেমপ্লেটগুলির সংজ্ঞা এটি একটি কম্পাইল সময় প্রক্রিয়া এবং btw মেটা প্রোগ্রামিং এই সংজ্ঞা ব্যবহার সম্পর্কে সব।


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

যাইহোক, আপনার কোড ব্যর্থ হওয়ার কারণ হল, যখন একটি টেমপ্লেট তাত্ক্ষণিক করা হয়, কম্পাইলার প্রদত্ত টেমপ্লেট আর্গুমেন্ট সহ একটি নতুন বর্গ তৈরি করে। উদাহরণ স্বরূপ:

template<typename T>
struct Foo
{
    T bar;
    void doSomething(T param) {/* do stuff using T */}
};

// somewhere in a .cpp
Foo<int> f; 

এই লাইনটি পড়ার সময়, কম্পাইলার একটি নতুন বর্গ তৈরি করবে (আসুন এটি FooInt ), যা নিম্নের সমতুল্য:

struct FooInt
{
    int bar;
    void doSomething(int param) {/* do stuff using int */}
}

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

এটির একটি সাধারণ সমাধান শিরোনাম ফাইলের টেমপ্লেট ঘোষণাটি লিখতে হয়, তারপরে একটি বাস্তবায়ন ফাইল (উদাহরণস্বরূপ .tpp) এ শ্রেণিকে বাস্তবায়ন করুন এবং শিরোনামের শেষে এই বাস্তবায়ন ফাইলটি অন্তর্ভুক্ত করুন।

// Foo.h
template <typename T>
struct Foo
{
    void doSomething(T param);
};

#include "Foo.tpp"

// Foo.tpp
template <typename T>
void Foo<T>::doSomething(T param)
{
    //implementation
}

এইভাবে, বাস্তবায়ন এখনও ঘোষণা থেকে পৃথক করা হয়, কিন্তু কম্পাইলার অ্যাক্সেসযোগ্য।

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

// Foo.h

// no implementation
template <typename T> struct Foo { ... };

//----------------------------------------    
// Foo.cpp

// implementation of Foo's methods

// explicit instantiations
template class Foo<int>;
template class Foo<float>;
// You will only be able to use Foo with int or float

আমার ব্যাখ্যা যথেষ্ট স্পষ্ট না হলে, আপনি এই বিষয়ে C ++ সুপার-FAQ দেখতে পারেন






c++-faq