সমস্ত ভার্চুয়াল ফাংশনগুলি উদ্ভূত শ্রেণিতে প্রয়োগ করা দরকার?


91

এটি সাধারণ প্রশ্নের মতো মনে হতে পারে তবে আমি উত্তর কোথাও খুঁজে পাচ্ছি না।

ধরুন আমার নিম্নলিখিতগুলি রয়েছে:

class Abstract {
public:
    virtual void foo() = 0;
    virtual void bar();
}

class Derived : Abstract {
public:
    virtual void foo();
}

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

উত্তর:


82

উদ্ভূত শ্রেণীর না না প্রয়োগ আছে সব ভার্চুয়াল ফাংশন নিজেদের। তাদের কেবল খাঁটিগুলি বাস্তবায়ন করা দরকার । 1 এর অর্থ Derivedপ্রশ্নে বর্গটি সঠিক। এটি পূর্বসূরি শ্রেণীর কাছ থেকে barবাস্তবায়নের উত্তরাধিকারী হয় Abstract,। (এটি ধরে নিয়েছে যে Abstract::barএটি কোথাও প্রয়োগ করা হয়েছে question প্রশ্নের কোডটি পদ্ধতিটি ঘোষণা করে তবে এটি সংজ্ঞা দেয় না You ট্রেনকির উত্তর শো হিসাবে আপনি এটিকে ইনলাইনটি সংজ্ঞায়িত করতে পারেন, বা আলাদাভাবে সংজ্ঞা দিতে পারেন can)


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


4
এবং এমনকি এটি (খাঁটি ভার্চুয়াল ফাংশনগুলির বাস্তবায়ন) কেবলমাত্র যদি তাদের তাত্ক্ষণিকভাবে উদ্দেশ্য করা হয় (নিজেরাই বিমূর্ত বেস বর্গ হিসাবে বিপরীতে)।
খ্রিস্টান রাউ

4
এটাই আমি ভেবেছিলাম। তবে এটি আমার প্রকল্পে করছি, এবং আমি একটি লিঙ্কিং ত্রুটি পেয়ে বলছি যে ডেরাইভড :: বার () এর জন্য একটি "অমীমাংসিত বাহ্যিক প্রতীক" রয়েছে; তবে আমি কখনই ডারাইভের মধ্যে বার ঘোষণা করিনি, সুতরাং লিঙ্কারটি কেন ফাংশন বডিটির সন্ধান করছে?
মিকাস্টাউব

4
@ পিক্সেলপুশার অবশ্যই Derived::barএকটি ফাংশন বডি আছে, যে Abstract::bar। সুতরাং এটি অনুবাদ ইউনিট বলে মনে হয় যেখানে এটি সংজ্ঞায়িত হয় (এটি কি কোথাও সংজ্ঞায়িত হয়?) অনুবাদ ইউনিটে যেখানে এটি বলা হয় সেখানে এটি লিঙ্কযুক্ত নয়।
খ্রিস্টান রাউ

4
@ রব: They only need to implement the pure ones.এটি বিভ্রান্তিকর। উদ্ভূত শ্রেণীর অগত্যা খাঁটি ভার্চুয়াল ফাংশন প্রয়োগ করার প্রয়োজন নেই
নওয়াজ

আমি সাহায্যের প্রশংসা করি তবে @ ট্রেনকি মাথায় পেরেকটি মারলেন। যদিও আপনি খ্রিস্টান রাউ ছিলেন সঠিক, কারণ এটি সংজ্ঞায়িত হয়নি।
মিকাস্টাউব

47

শুধুমাত্র খাঁটি ভার্চুয়াল পদ্ধতিগুলি উদ্ভূত শ্রেণিতে প্রয়োগ করতে হবে, তবে আপনার এখনও অন্যান্য ভার্চুয়াল পদ্ধতিগুলির একটি সংজ্ঞা (এবং কেবল একটি ঘোষণা নয়) দরকার। আপনি যদি একটি সরবরাহ না করেন তবে লিঙ্কারটি খুব ভাল অভিযোগ করতে পারে।

সুতরাং, কেবলমাত্র {}আপনার alচ্ছিক ভার্চুয়াল পদ্ধতিটি আপনাকে খালি ডিফল্ট বাস্তবায়ন দেয়:

class Abstract {
public:
    virtual void foo() = 0; // pure virtual must be overridden
    virtual void bar() {}   // virtual with empty default implementation
};

class Derived : Abstract {
public:
    virtual void foo();
};

আরও জড়িত ডিফল্ট বাস্তবায়ন যদিও পৃথক উত্স ফাইলে যাবে।


7

আইএসও সি ++ স্ট্যান্ডার্ড নির্দিষ্ট করে যে কোনও শ্রেণীর খাঁটি-ভার্চুয়াল নয় এমন সমস্ত ভার্চুয়াল পদ্ধতি অবশ্যই সংজ্ঞায়িত করা উচিত।


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

আপনার কোড উদাহরণের উপরের নিয়ম অনুসারে, virtual void bar();বেস শ্রেণিতে একটি সংজ্ঞা প্রয়োজন।

তথ্যসূত্র:

সি ++ ০৩ স্ট্যান্ডার্ড: 10.3 ভার্চুয়াল ফাংশন [ক্লাসে ভার্চুয়াল]

একটি শ্রেণিতে ঘোষিত একটি ভার্চুয়াল ফাংশন সংজ্ঞায়িত করা হবে, বা সেই শ্রেণিতে শুদ্ধ (10.4) বা উভয় হিসাবে ঘোষণা করা হবে; তবে কোনও ডায়াগনস্টিকের প্রয়োজন নেই (3.2)।

সুতরাং হয় আপনি ফাংশন বিশুদ্ধ ভার্চুয়াল করা উচিত বা এর জন্য একটি সংজ্ঞা প্রদান করা উচিত।

জিসিসি FAQ doccuments ভাল হিসাবে এটি:

আইএসও সি ++ স্ট্যান্ডার্ড নির্দিষ্ট করে যে খাঁটি-ভার্চুয়াল নয় এমন শ্রেণীর সমস্ত ভার্চুয়াল পদ্ধতি অবশ্যই সংজ্ঞায়িত করা উচিত, তবে এই নিয়ম লঙ্ঘনের জন্য কোনও ডায়গনিস্টিকের প্রয়োজন নেই [class.virtual]/8। এই অনুমানের উপর ভিত্তি করে, জিসিসি কেবল অনুবাদ সংস্থায় স্পষ্টভাবে সংজ্ঞায়িত কনস্ট্রাক্টর, অ্যাসাইনমেন্ট অপারেটর, ডেস্ট্রাক্টর এবং একটি শ্রেণীর ভার্চুয়াল টেবিলটি প্রেরণ করবে যা তার প্রথম অ-ইনলাইন পদ্ধতিটিকে সংজ্ঞায়িত করে।

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

সমাধানটি নিশ্চিত করা হয় যে খাঁটি নয় এমন সমস্ত ভার্চুয়াল পদ্ধতি সংজ্ঞায়িত হয়েছে to নোট করুন যে কোনও ডেস্ট্রাক্টরকে সংজ্ঞা দিতে হবে এমনকি যদি এটি খাঁটি-ভার্চুয়াল হিসাবে ঘোষণা করা হয় [class.dtor]/7


3

হ্যাঁ, এটি ঠিক আছে ... একটি বিমূর্ত বেস বর্গ থেকে প্রাপ্ত ক্লাসটি ইনস্ট্যান্ট করার জন্য আপনাকে কেবল কোনও খাঁটি ভার্চুয়াল ফাংশন প্রয়োগ করতে হবে।


1

হ্যাঁ, এটি সঠিক যে একজন উত্সর্গীকৃত শ্রেণিকে ফাংশনটি ওভাররাইড করতে হবে যা প্যারেন্ট ক্লাসে খাঁটি ভার্চুয়াল। খাঁটি ভার্চুয়াল ফাংশন সম্পন্ন পিতামাতার ক্লাসটিকে কেবল অ্যাবস্ট্রাক্ট ক্লাস বলা হয় কারণ এটি শিশু শ্রেণিকে অবশ্যই তাদের নিজের খাঁটি ভার্চুয়াল ফাংশন দেবে।

সাধারন ভার্চুয়াল ফাংশনগুলির জন্য: - তাদের আরও ওভাররাইড করা প্রয়োজন হয় না, কারন কিছু শিশু শ্রেণীর সেই ক্রিয়াকলাপ থাকতে পারে, কারও কারও কাছে নাও থাকতে পারে।

ভার্চুয়াল ফাংশন মেকানিজমের মূল উদ্দেশ্য রান টাইম পলিমারফিজম, খাঁটি ভার্চুয়াল ফাংশন (অ্যাবস্ট্রাক্ট ক্লাস) এর মূল উদ্দেশ্যটি নিজের শরীরের সাথে একই নাম ফাংশন রাখা বাধ্যতামূলক করে কিনা।

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