যদি আমি একটি নির্দিষ্ট ধরণের একটি ভেরিয়েবল সংজ্ঞায়িত করি (যা আমি জানি, কেবল ভেরিয়েবলের বিষয়বস্তুর জন্য ডেটা বরাদ্দ করে) তবে এটি কোন ধরণের ভেরিয়েবলের ট্র্যাক রাখে?
যদি আমি একটি নির্দিষ্ট ধরণের একটি ভেরিয়েবল সংজ্ঞায়িত করি (যা আমি জানি, কেবল ভেরিয়েবলের বিষয়বস্তুর জন্য ডেটা বরাদ্দ করে) তবে এটি কোন ধরণের ভেরিয়েবলের ট্র্যাক রাখে?
উত্তর:
চলক (বা আরও সাধারণভাবে: "সি" এর অর্থে "অবজেক্ট") রানটাইমের সময় তাদের ধরণের সঞ্চয় করে না। যতক্ষণ না মেশিন কোড সম্পর্কিত, কেবলমাত্র টাইপযুক্ত মেমরি। পরিবর্তে, এই ডেটাতে করা ক্রিয়াকলাপগুলি ডেটাটিকে নির্দিষ্ট ধরণের হিসাবে ব্যাখ্যা করে (যেমন একটি ফ্লোট হিসাবে বা পয়েন্টার হিসাবে)। প্রকারগুলি কেবল সংকলক দ্বারা ব্যবহৃত হয়।
উদাহরণস্বরূপ, আমাদের স্ট্রাক্ট বা ক্লাস struct Foo { int x; float y; };
এবং একটি ভেরিয়েবল থাকতে পারে Foo f {}
। ক্ষেত্রের অ্যাক্সেস auto result = f.y;
কীভাবে সংকলন করা যায়? সংকলকটি জানে যে f
এটি কোনও ধরণের একটি অবজেক্ট Foo
এবং Foo
ob-প্রকল্পগুলির বিন্যাসটি জানে । প্ল্যাটফর্ম-নির্দিষ্ট বিশদের উপর নির্ভর করে এটি "পয়েন্টারটি শুরুতে নিন f
, 4 বাইট যুক্ত করুন, তারপরে 4 বাইট লোড করুন এবং এই ডেটাটিকে একটি ফ্লোট হিসাবে ব্যাখ্যা করুন " হিসাবে সংকলিত হতে পারে many ) ফ্লোটগুলি বা ইনটগুলি লোড করার জন্য বিভিন্ন প্রসেসরের নির্দেশাবলী রয়েছে।
একটি উদাহরণ যেখানে সি ++ টাইপ সিস্টেমটি আমাদের জন্য প্রকারের উপর নজর রাখতে পারে না তা হল একটি ইউনিয়ন union Bar { int as_int; float as_float; }
। একটি ইউনিয়নে বিভিন্ন ধরণের একটি অবজেক্ট থাকে। যদি আমরা কোনও ইউনিয়নে কোনও বস্তু সঞ্চয় করি তবে এটি ইউনিয়নের সক্রিয় প্রকার। আমাদের কেবল সেই ধরণের ইউনিয়ন থেকে ফিরে আসার চেষ্টা করতে হবে, অন্য যে কোনও কিছুই হবে অপরিবর্তিত আচরণ। সক্রিয় প্রকারটি কী তা প্রোগ্রাম করার সময় আমরা "জানি", অথবা আমরা একটি ট্যাগ ইউনিয়ন তৈরি করতে পারি যেখানে আমরা আলাদাভাবে কোনও টাইপ ট্যাগ (সাধারণত একটি এনাম) সঞ্চয় করি। এটি সি তে একটি সাধারণ কৌশল, তবে আমাদের ইউনিয়ন এবং টাইপ ট্যাগটি সিঙ্কে রাখতে হবে কারণ এটি মোটামুটি ত্রুটিযুক্ত। একটি void*
পয়েন্টার একটি ইউনিয়নের অনুরূপ তবে কেবল ফাংশন পয়েন্টার ব্যতীত পয়েন্টার অবজেক্টগুলি ধরে রাখতে পারে।
সি ++ অজানা ধরণের জিনিসগুলির সাথে মোকাবিলা করার জন্য দুটি আরও ভাল প্রক্রিয়া সরবরাহ করে: আমরা প্রকার মুছে ফেলার জন্য অবজেক্ট-ওরিয়েন্টেড কৌশলগুলি ব্যবহার করতে পারি (কেবলমাত্র ভার্চুয়াল পদ্ধতির মাধ্যমে বস্তুর সাথে ইন্টারঅ্যাক্ট করতে হবে যাতে আমাদের প্রকৃত প্রকারটি জানতে প্রয়োজন না হয়), বা আমরা করতে পারি ব্যবহার std::variant
, টাইপ-নিরাপদ ইউনিয়ন এক প্রকার।
একটি ঘটনা রয়েছে যেখানে সি ++ কোনও সামগ্রীর ধরণ সংরক্ষণ করে: যদি বস্তুর শ্রেণিতে কোনও ভার্চুয়াল পদ্ধতি থাকে (একটি "পলিমারফিক টাইপ", ওরফে ইন্টারফেস)। ভার্চুয়াল পদ্ধতিতে কলটির লক্ষ্য সংকলনের সময় অজানা এবং রান অব টাইম অবজেক্টের গতিশীল ধরণের ("ডায়নামিক প্রেরণ") এর উপর ভিত্তি করে সমাধান করা হয়। বেশিরভাগ সংকলকগণ বস্তুর শুরুতে ভার্চুয়াল ফাংশন টেবিল ("ভ্যাটেবল") সঞ্চয় করে এটি প্রয়োগ করে। রানটাইমে অবজেক্টের ধরণ পেতে ভিটিবেলও ব্যবহার করা যেতে পারে। তারপরে আমরা কম্পাইল-টাইম জ্ঞাত স্ট্যাটিক ধরণের একটি অভিব্যক্তি এবং রানটাইমের সময় কোনও বস্তুর গতিশীল প্রকারের মধ্যে পার্থক্য আঁকতে পারি।
সি ++ আমাদের typeid()
অপারেটরের সাথে একটি বস্তুর গতিশীল প্রকারের পরীক্ষা করতে দেয় যা আমাদের একটি std::type_info
বস্তু দেয় । হয় সংকলক কম্পাইল সময়ে অবজেক্টের ধরণটি জানে বা সংকলকটি প্রয়োজনীয় ধরণের তথ্য অবজেক্টের অভ্যন্তরে সঞ্চিত করেছে এবং রানটাইম এ এটি পুনরুদ্ধার করতে পারে।
void*
)।
typeid(e)
অভিব্যক্তির স্থিতিশীল প্রকারকে আত্মপ্রকাশ করে e
। যদি স্ট্যাটিক টাইপটি একটি বহুকর্মী ধরণের হয় তবে অভিব্যক্তিটি মূল্যায়ন করা হবে এবং সেই অবজেক্টের গতিশীল প্রকারটি পুনরুদ্ধার করা হবে। আপনি অজানা টাইপের স্মৃতিতে টাইপড নির্দেশ করতে পারবেন না এবং দরকারী তথ্য পাবেন। ইউনিয়নের উদাহরণস্বরূপ, ইউনিয়নের বস্তু নয়, ইউনিয়নের বর্ণনা দেয়। একটির টাইপড কেবল একটি শূন্য void*
পয়েন্টার। এবং এগুলির void*
বিষয়বস্তুগুলি পাওয়ার জন্য এটিকে অবহেলা করা সম্ভব নয় । সি ++ তে কোনও বক্সিং নেই, যতক্ষণ না স্পষ্টভাবে সেভাবে প্রোগ্রাম করা হয়।
অন্য উত্তরটি প্রযুক্তিগত দিকটি ভালভাবে ব্যাখ্যা করে তবে আমি কিছু সাধারণ "মেশিনের কোড সম্পর্কে কীভাবে চিন্তা করব" যুক্ত করতে চাই।
সংকলনের পরে মেশিন কোডটি বেশ বোবা, এবং এটি সত্যই ধরে নিয়েছে যে সমস্ত কিছু ইচ্ছা মত কাজ করে। বলুন আপনার মত একটি সাধারণ ফাংশন আছে
bool isEven(int i) { return i % 2 == 0; }
এটি একটি অন্তর্নির্মিত লাগে, এবং একটি বুল আউট spits।
আপনি এটি সংকলন করার পরে, আপনি এটি এই স্বয়ংক্রিয় কমলা জুসার জাতীয় কিছু হিসাবে ভাবতে পারেন:
এটি কমলা নেয়, এবং রস দেয়। এটি কী ধরণের বস্তুগুলিতে প্রবেশ করে তা স্বীকৃতি দেয়? না, তারা কমলা হওয়ার কথা। যদি এটি কমলা পরিবর্তে একটি আপেল পায় তবে কী হবে? সম্ভবত এটি বিরতি হবে। এটি কোনও বিষয় নয়, কারণ দায়িত্বশীল একজন মালিক এটিকে এভাবে ব্যবহার করার চেষ্টা করবেন না।
উপরের ফাংশনটি একই রকম: এটি ইনটগুলি নেওয়ার জন্য ডিজাইন করা হয়েছে এবং অন্য কোনও কিছু খাওয়ালে এটি কিছুটা ভেঙে বা অপ্রাসঙ্গিকভাবে কাজ করতে পারে। এটি (সাধারণত) কিছু যায় আসে না, কারণ সংকলক (সাধারণত) পরীক্ষা করে যে এটি কখনও ঘটে না - এবং প্রকৃতপক্ষে সুসংগঠিত কোডে কখনও তা ঘটে না। যদি সংকলক কোনও ফাংশন ভুল টাইপ করা মান পেতে পারে এমন সম্ভাবনা সনাক্ত করে তবে এটি কোডটি সংকলন করতে অস্বীকার করে এবং পরিবর্তে প্রকারের ত্রুটিগুলি ফিরিয়ে দেয়।
সতর্কবাণীটি হ'ল এমন কিছু সংঘটিত কোড রয়েছে যা সংকলক পাস করবে। উদাহরণগুলি হ'ল:
void*
থেকে orange*
যখন পয়েন্টার অপর প্রান্তের একটি আপেল হয়,যেমনটি বলা হয়েছে, সংকলিত কোডটি ঠিক জুসার মেশিনের মতো - এটি কী প্রক্রিয়া করে তা জানে না, এটি কেবল নির্দেশগুলি কার্যকর করে। এবং নির্দেশাবলী ভুল হলে, এটি বিরতি। এজন্য সি ++ এর উপরের সমস্যাগুলি অনিয়ন্ত্রিত ক্র্যাশগুলির ফলাফল।
void*
কাছে coerces foo*
স্বাভাবিক গাণিতিক পদোন্নতি, union
টাইপ punning, NULL
বনাম nullptr
, এমনকি মাত্র থাকার একটি খারাপ পয়েন্টার UB, ইত্যাদি হয় কিন্তু আমি বস্তুগত আপনার উত্তর উন্নতি হবে সেগুলো খুঁজে সব তালিকা মনে করি না, তাই এটি সম্ভবত ছুটি সেরা এটা যেমন হয়।
void*
সুস্পষ্টভাবে রূপান্তর করে না foo*
, এবং union
টাইপ পেনিং সমর্থন করে না (ইউবি রয়েছে)।
ভেরিয়েবলের সি এর মতো ভাষায় প্রচুর মৌলিক বৈশিষ্ট্য রয়েছে:
আপনার উত্স কোডে , অবস্থান, (5) ধারণামূলক, এবং এই অবস্থানটি তার নাম দ্বারা উল্লেখ করা হয়েছে, (1)। সুতরাং, একটি ভেরিয়েবল ডিক্লেয়ারেশন মান, (6) এর অবস্থান এবং স্থান তৈরি করতে ব্যবহৃত হয় এবং উত্সের অন্যান্য লাইনে আমরা সেই অবস্থানটি উল্লেখ করি এবং কিছু অভিব্যক্তিতে ভেরিয়েবলের নাম রেখে এটির মানটি উল্লেখ করি।
কেবলমাত্র কিছুটা সরলকরণ, একবার আপনার প্রোগ্রামটি সংকলক দ্বারা মেশিন কোডে অনুবাদ করা হলে, অবস্থান, (5) কিছু মেমরি বা সিপিইউ নিবন্ধের অবস্থান এবং ভেরিয়েবলের রেফারেন্সের যে কোনও উত্স কোড এক্সপ্রেশনগুলি মেমরি কোড অনুক্রমগুলিতে অনুবাদ করা হয় যা সেই মেমরিকে উল্লেখ করে অথবা সিপিইউ নিবন্ধের অবস্থান।
সুতরাং, অনুবাদটি শেষ হয়ে গেলে এবং প্রোগ্রামটি প্রসেসরে চলমান অবস্থায়, ভেরিয়েবলগুলির নামগুলি কার্যকরভাবে মেশিন কোডের মধ্যে ভুলে যায় এবং, সংকলক দ্বারা উত্পন্ন নির্দেশাবলী কেবল ভেরিয়েবলের নির্ধারিত অবস্থানগুলিকে বোঝায় (পরিবর্তে তাদের পরিবর্তে) নামগুলি নয়)। আপনি যদি ডিবাগিং করছেন এবং ডিবাগিংয়ের জন্য অনুরোধ করছেন তবে নামের সাথে সম্পর্কিত ভেরিয়েবলের অবস্থানটি প্রোগ্রামের মেটাডেটাতে যুক্ত করা হয়, যদিও প্রসেসর এখনও লোকেশনগুলি ব্যবহার করে মেশিন কোডের নির্দেশাবলী দেখেন (সেই মেটাডেটা নয়)। (এটি লিখিতকরণ, লোডিং এবং গতিশীল অনুসন্ধানের উদ্দেশ্যে প্রোগ্রামের মেটাডেটাতে কিছু নাম রয়েছে বলে এটি একটি অতি সরলকরণ - এখনও প্রসেসর কেবল প্রোগ্রামটির জন্য বলা মেশিন কোডের নির্দেশাবলী কার্যকর করে এবং এই মেশিন কোডে নামগুলি রয়েছে) অবস্থানগুলিতে রূপান্তরিত হয়েছে))
প্রকার, সুযোগ এবং আজীবন ক্ষেত্রেও এটি একই। সংকলক উত্পন্ন মেশিন কোড নির্দেশাবলী লোকেশনটির মেশিন সংস্করণটি জানে। অন্যান্য বৈশিষ্ট্য যেমন টাইপ করা যায় এমন নির্দিষ্ট নির্দেশাবলী হিসাবে ভেরিয়েবলের অবস্থান অ্যাক্সেস করে অনুবাদিত উত্স কোডে সংকলিত হয়। উদাহরণস্বরূপ, যদি প্রশ্নের ভেরিয়েবলটি একটি স্বাক্ষরিত 8-বিট বাইট বনাম একটি স্বাক্ষরযুক্ত 8-বিট বাইট হয়, তবে উত্স কোডটিতে যে ভেরিয়েবলটি উল্লেখ করা হয়েছে তাতে অনুবাদ হবে, বলুন, স্বাক্ষরিত বাইট লোড বনাম স্বাক্ষরযুক্ত বাইট লোড, (সি) ভাষার নিয়মগুলি সন্তুষ্ট করার জন্য প্রয়োজনীয়। ভেরিয়েবলের ধরণটি মেশিনের নির্দেশিকায় সোর্স কোডটির অনুবাদে এনকোড করা হয়, যা সিপিইউকে নির্দেশ দেয় যে মেমরি বা সিপিইউ নিবন্ধের অবস্থানটি প্রতিবার এবং প্রতিটি সময় ভেরিয়েবলের অবস্থানটি ব্যবহার করার জন্য কীভাবে ব্যাখ্যা করা যায়।
সারমর্মটি হ'ল প্রসেসরের মেশিন কোড ইন্সট্রাকশন সেটে নির্দেশাবলী (এবং আরও নির্দেশাবলীর) মাধ্যমে কী করতে হবে তা আমাদের সিপিইউকে জানাতে হবে। প্রসেসর এটি কী করেছে বা কী বলা হয়েছিল সে সম্পর্কে খুব কম মনে পড়ে - এটি কেবলমাত্র প্রদত্ত নির্দেশাবলী কার্যকর করে এবং সঠিকভাবে ভেরিয়েবলগুলি ম্যানিপুলেট করার জন্য নির্দেশের ক্রমগুলির সম্পূর্ণ সেট প্রদান করা সংকলক বা সমাবেশ ভাষা প্রোগ্রামারের কাজ।
প্রসেসর সরাসরি কিছু মৌলিক ডেটা ধরণের সমর্থন করে যেমন বাইট / শব্দ / ইনট / দীর্ঘ স্বাক্ষরিত / স্বাক্ষরিত, ভাসমান, ডাবল ইত্যাদি etc আপনি যদি একইভাবে মেমরির অবস্থানটি স্বাক্ষরিত বা স্বাক্ষরযুক্ত হিসাবে একইভাবে আচরণ করেন তবে প্রসেসর সাধারণত অভিযোগ বা আপত্তি জানাতে পারবেন না for উদাহরণস্বরূপ, যদিও এটি প্রোগ্রামে সাধারণত একটি যুক্তি ত্রুটি হতে পারে। ভেরিয়েবলের সাথে প্রতিটি মিথস্ক্রিয়ায় প্রসেসরকে নির্দেশ দেওয়া প্রোগ্রামিংয়ের কাজ।
এই মৌলিক আদিম প্রকারের বাইরে, আমাদের ডেটা স্ট্রাকচারগুলিতে জিনিসগুলি এনকোড করতে হবে এবং সেই আদিমগুলির পদগুলিতে এগুলি পরিচালনা করতে অ্যালগরিদম ব্যবহার করতে হবে।
সি ++ তে বহুবর্ষের জন্য শ্রেণি শ্রেণিবিন্যাসের সাথে জড়িত অবজেক্টগুলির একটি পয়েন্টার থাকে, সাধারণত অবজেক্টের শুরুতে, যা শ্রেণি-নির্দিষ্ট ডেটা কাঠামোকে বোঝায়, যা ভার্চুয়াল প্রেরণ, castালাই ইত্যাদিতে সহায়তা করে ..
সংক্ষেপে, প্রসেসর অন্যথায় স্টোরেজ অবস্থানগুলির উদ্দেশ্যে ব্যবহারটি জানে না বা মনে রাখে না - এটি প্রোগ্রামটির মেশিন কোড নির্দেশাবলী কার্যকর করে যা সিপিইউ রেজিস্ট্রারগুলিতে এবং প্রধান মেমোরিতে স্টোরেজ কীভাবে পরিচালনা করতে হয় তা জানিয়ে দেয়। প্রোগ্রামিং, তারপরে, সফ্টওয়্যারটির (এবং প্রোগ্রামারদের) স্টোরেজটি অর্থবহভাবে ব্যবহার করা এবং প্রসেসরের কাছে মেশিন কোডের নির্দেশাবলীর একটি ধারাবাহিক সেট উপস্থাপন করা যা পুরোপুরি বিশ্বস্তভাবে প্রোগ্রামটি সম্পাদন করে।
useT1(&unionArray[i].member1); useT2(&unionArray[j].member2); useT1(&unionArray[i].member1);
, ঝনঝন এবং জিসিসি অনুমান করে যে পয়েন্টারটি unionArray[j].member2
অ্যাক্সেস করতে পারে না unionArray[i].member1
যদিও উভয়ই একই থেকে প্রাপ্ত unionArray[]
।
যদি আমি একটি নির্দিষ্ট ধরণের একটি ভেরিয়েবল সংজ্ঞায়িত করি তবে এটি কীভাবে এটি ভেরিয়েবলের প্রকারের ট্র্যাক রাখে।
এখানে দুটি প্রাসঙ্গিক পর্যায় রয়েছে:
সি সংকলক সি কোডটি মেশিনের ভাষায় সংকলন করে। সংকলকটিতে সমস্ত তথ্য রয়েছে যা এটি আপনার উত্স ফাইল (এবং গ্রন্থাগারগুলি এবং এটির কাজটি করার জন্য যা কিছু অন্যান্য জিনিস প্রয়োজন) থেকে পেতে পারে। সি সংকলকটি কী বোঝায় তা ট্র্যাক করে। সি সংকলক জানে যে আপনি যদি কোনও ভেরিয়েবলকে ঘোষনা করেন char
তবে এটি চর।
এটি তথাকথিত "প্রতীক টেবিল" ব্যবহার করে এটি করে যা ভেরিয়েবলের নাম, তাদের প্রকার এবং অন্যান্য তথ্য তালিকাভুক্ত করে। এটি একটি জটিল তথ্য কাঠামো, তবে আপনি এটিকে মানব-পঠনযোগ্য নামগুলির অর্থ কী তা ট্র্যাক করা হিসাবে ভাবতে পারেন। সংকলক থেকে বাইনারি আউটপুটে, এর মতো কোনও চলক নাম আর উপস্থিত হয় না (যদি আমরা optionচ্ছিক ডিবাগ তথ্য উপেক্ষা করি যা প্রোগ্রামার দ্বারা অনুরোধ করা যেতে পারে)।
সংকলকটির আউটপুট - সংকলিত এক্সিকিউটেবল - মেশিন ল্যাঙ্গুয়েজ, যা আপনার ওএস দ্বারা র্যামে লোড করা হয় এবং আপনার সিপিইউ দ্বারা সরাসরি চালিত হয়। যন্ত্রের ভাষায়, "টাইপ" এর কোনও ধারণা নেই - এটির কেবলমাত্র কমান্ড রয়েছে যা র্যামের কোনও স্থানে কাজ করে। কমান্ড প্রকৃতপক্ষে একটি নির্দিষ্ট টাইপ তারা চালনা আছে (অর্থাত, সেখানে একটি মেশিন ভাষা কমান্ড "এই দুটি 16 বিট র্যাম অবস্থানে 0x100 এবং 0x521 সংরক্ষিত পূর্ণসংখ্যার জুড়ুন" হতে পারে), কিন্তু কোন তথ্য নেই কোন জায়গায় সিস্টেম যে এই অবস্থানগুলিতে বাইটগুলি আসলে পূর্ণসংখ্যার প্রতিনিধিত্ব করে। সেখানে টাইপ ত্রুটি থেকে কোনো সুরক্ষা সব এখানে।
char *ptr = 0x123
সি এর মতো ) বলা সম্ভব হয় না । আমি বিশ্বাস করি আমার "পয়েন্টার" শব্দটির ব্যবহারটি এই প্রসঙ্গে বেশ পরিষ্কার হওয়া উচিত। যদি তা না হয় তবে নির্দ্বিধায় আমাকে মাথা তুলে দিন এবং আমি উত্তরে একটি বাক্য যুক্ত করব।
কয়েকটি গুরুত্বপূর্ণ বিশেষ কেস রয়েছে যেখানে সি টাইম রান টাইমে কোনও ধরণের সঞ্চয় করে।
ক্লাসিক সমাধানটি একটি বৈষম্যমূলক ইউনিয়ন: এমন একটি ডেটা স্ট্রাকচার যা বিভিন্ন ধরণের অবজেক্টের মধ্যে একটি থাকে, এবং এমন একটি ক্ষেত্র যা বলে যে এটি বর্তমানে কী ধরণের রয়েছে। একটি টেম্প্লেটেড সংস্করণ সি ++ স্ট্যান্ডার্ড লাইব্রেরিতে রয়েছে std::variant
। সাধারণত, ট্যাগটি একটি হতে পারে enum
তবে আপনার যদি আপনার ডেটার জন্য সমস্ত বিট স্টোরেজের প্রয়োজন না হয় তবে এটি একটি বিটফিল্ড হতে পারে।
এর অন্যান্য সাধারণ ক্ষেত্রে গতিশীল টাইপিং। যখন আপনার class
কোনও virtual
ফাংশন রয়েছে, প্রোগ্রামটি ভার্চুয়াল ফাংশন সারণীতে সেই ফাংশনের একটি পয়েন্টার সংরক্ষণ করবে , যা এটি class
নির্মাণের পরে প্রতিটি উদাহরণের জন্য সূচনা করবে । সাধারণত, এর অর্থ সমস্ত শ্রেণীর দৃষ্টান্তের জন্য একটি ভার্চুয়াল ফাংশন টেবিল এবং প্রতিটি উদাহরণ উপযুক্ত টেবিলের জন্য একটি পয়েন্টার ধারণ করে। (এটি সময় এবং স্মৃতি সাশ্রয় করে কারণ একক পয়েন্টারের চেয়ে টেবিলটি অনেক বড় হবে)) আপনি যখন virtual
কোনও পয়েন্টার বা রেফারেন্সের মাধ্যমে সেই ফাংশনটি কল করবেন তখন প্রোগ্রামটি ভার্চুয়াল সারণীতে ফাংশন পয়েন্টারটি সন্ধান করবে। (যদি এটি সংকলনের সময় সঠিক ধরণেরটি জানেন তবে এটি এই পদক্ষেপটি এড়িয়ে যেতে পারে)) এটি কোডটি বেস শ্রেণীর পরিবর্তে ডাইরাইটেড টাইপের প্রয়োগ কল করতে পারে allows
জিনিস যে এখানে প্রাসঙ্গিক করে তোলে: প্রতিটি ofstream
একটি পয়েন্টার রয়েছে ofstream
ভার্চুয়াল টেবিল, প্রতিটি ifstream
থেকে ifstream
ভার্চুয়াল টেবিল ইত্যাদি। শ্রেণি শ্রেণিবিন্যাসের জন্য, ভার্চুয়াল টেবিল পয়েন্টারটি ট্যাগ হিসাবে পরিবেশন করতে পারে যা প্রোগ্রামকে জানায় যে শ্রেণীর অবজেক্টটি কী ধরণের!
যদিও ভাষার স্ট্যান্ডার্ড এমন লোকগুলিকে না জানায় যারা সংকলকগুলি ডিজাইন করেন তাদের কীভাবে হুডের নীচে রানটাইম বাস্তবায়ন করতে হবে, আপনি কীভাবে আশা করতে পারেন dynamic_cast
এবং typeof
কাজ করতে পারেন ।