ডাইরেক্ট ক্লাসে একই নামের সাথে পৃথক স্বাক্ষর সহ ফাংশন


92

আমার একই নামে একটি ফাংশন রয়েছে তবে বেস এবং উত্পন্ন ক্লাসে বিভিন্ন স্বাক্ষর সহ। যখন আমি ভিত্তি শ্রেণীর ফাংশনটি অন্য শ্রেণিতে প্রাপ্ত হয়েছে যা উত্তরাধিকার সূত্রে উত্তরাধিকার সূত্রে ব্যবহার করার চেষ্টা করছি তখন আমি একটি ত্রুটি পাই। নিম্নলিখিত কোডটি দেখুন:

class A
{
    public:
    void foo(string s){};
};

class B : public A
{
    public:
    int foo(int i){};
};

class C : public B
{
    public:
    void bar()
    {
        string s;
        foo(s);
    }
};

আমি জিসিসি সংকলক থেকে নিম্নলিখিত ত্রুটিটি পেয়েছি:

In member function `void C::bar()': no matching function for call to `C::foo(std::string&)' candidates are: int B::foo(int)

আমি যদি int foo(int i){};ক্লাস থেকে অপসারণ করি Bবা আমি যদি এর নাম পরিবর্তন করি তবে foo1সবকিছু ঠিকঠাক হয়।

এতে সমস্যা কী?


4
প্রযুক্তিগতভাবে এই প্রশ্নের সদৃশ তবে এটির একটি আরও ভাল শিরোনাম এবং উত্তর রয়েছে।
ট্রাববাদ’র

উত্তর:


79

প্রাপ্ত ক্লাসগুলিতে ফাংশন যা বেস ক্লাসগুলিতে ফাংশনগুলিকে ওভাররাইড করে না তবে একই নাম রয়েছে সেগুলি বেস শ্রেণিতে একই নামের অন্যান্য ক্রিয়াকলাপগুলি আড়াল করে রাখে

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

যদি আপনাকে বেস ফাংশনটি কল করতে হয় তবে আপনার কলটি ব্যবহার করে স্কোপ করতে হবে A::foo(s)। নোট করুন যে A::foo(string)এটি একই সাথে কোনও ভার্চুয়াল ফাংশন প্রক্রিয়াটি অক্ষম করে ।


13
লিডডিবির উত্তরটিও পড়ুন: আপনি বিতে 'এ ::
ফু

সত্য, আমি কেবল একটি সমাধান খুঁজছিলাম যা কল সাইটে ব্যবহার করা যেতে পারে, বেস স্তরক্রমকে স্থির হিসাবে বিবেচনা করে।
সিবি বেইলি

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

109

কারণ এটি আপনার ঘাঁটির কোনও একটিতে নাম সন্ধান করে তবে নাম অনুসন্ধান বন্ধ হয়ে যায়। এটি অন্যান্য ঘাঁটিগুলির বাইরেও দেখবে না। বি এর ফাংশনটি এ এর ​​ক্রিয়াকলাপকে ছায়া দিচ্ছে আপনাকে এ এর ​​ফাংশনটি বি এর স্কোপগুলিতে পুনরায় ঘোষণা করতে হবে, যাতে উভয় ফাংশন বি এবং সি এর মধ্যে দৃশ্যমান হয়:

class A
{
    public:
    void foo(string s){};
};

class B : public A
{
    public:
    int foo(int i){};
    using A::foo;
};

class C : public B
{
    public:
    void bar()
    {
        string s;
        foo(s);
    }
};

সম্পাদনা করুন: স্ট্যান্ডার্ড দেয় আসল বিবরণটি (10.2 / 2 থেকে):

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

এটি অন্য জায়গায় বলার জন্য নিম্নলিখিতটি রয়েছে (এর ঠিক উপরে):

আইডি-এক্সপ্রেশনটির জন্য [ "foo" এর মতো কিছু ]] নামের শ্রেণিবদ্ধ হয়ে শুরু হয়; একটি যোগ্য-আইডির জন্য [ "এ :: ফু" এর মতো কিছু, এ নেস্টেড-নেম-স্পেসিফায়ার ], নেস্টেড-নেম-স্পেসিফায়ারের সুযোগে নাম সন্ধান শুরু হয়। নাম অনুসন্ধান অ্যাক্সেস নিয়ন্ত্রণের আগে স্থান নেয় (3.4, ধারা 11)।

([...] আমার দেওয়া) দ্রষ্টব্যটির অর্থ হ'ল বিতে আপনার ফুও ব্যক্তিগত থাকলেও, এ-তে থাকা ফু খুঁজে পাওয়া যাবে না (কারণ অ্যাক্সেস নিয়ন্ত্রণ পরে ঘটে)।


litb, আপনার উত্তরের জন্য ধন্যবাদ। তবে আমি যখন আপনার কোডটি সংকলিত করার চেষ্টা করি তখন আমি পেয়েছি: void A::foo(class basic_string<char,char_traits<char>,allocator<char> >)' in স্থানীয় পদ্ধতির কারণে 'বি বি :: ফূ (ইনট)' একই নামের সাথে ক্লাস বি'র অ্যাক্সেস সামঞ্জস্য করতে পারে না । সম্ভবত এটি কারণ আমি
জিসিসি-র

4
হ্যাঁ, অবশ্যই একটি সংকলক বাগ পুরানো সংকলকগুলি "এ :: ফু" ব্যবহার করত; "এ :: ফু ব্যবহার করে" এর পরিবর্তে; তবে প্রাক্তনটি সি ++ এ অবমাননিত।
জোহানেস স্কাউব - লিটব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.