অপারেটর ওভারলোডিং: সদস্য ফাংশন বনাম অ-সদস্য ফাংশন?


121

আমি পড়েছি যে সদস্য ফাংশন হিসাবে ঘোষিত একটি ওভারলোডেড অপারেটরটি অসম্পূর্ণ কারণ এটিতে কেবল একটি প্যারামিটার থাকতে পারে এবং অন্য প্যারামিটারটি স্বয়ংক্রিয়ভাবে পাস করা হয় thisপয়েন্টার। সুতরাং তাদের তুলনা করার জন্য কোনও মান বিদ্যমান নেই। অন্যদিকে, ওভারলোডেড অপারেটরকে একটি প্রতিসাম্য হিসাবে ঘোষণা করা friendহয় কারণ আমরা একই ধরণের দুটি যুক্তি পাস করি এবং সেজন্য, তাদের তুলনা করা যায়।

আমার প্রশ্ন হ'ল আমি যখন এখনও কোনও পয়েন্টারের লভ্যালুটিকে একটি রেফারেন্সের সাথে তুলনা করতে পারি, তখন বন্ধুরা কেন পছন্দ হয়? (একটি অসম্পূর্ণ সংস্করণ ব্যবহার করে প্রতিসম হিসাবে একই ফলাফল দেয়) এসটিএল অ্যালগরিদমগুলি কেন কেবলমাত্র প্রতিসম ভার্সন ব্যবহার করে?


11
আপনার প্রশ্নটি কেবল বাইনারি অপারেটর সম্পর্কে about সমস্ত ওভারলোডেড অপারেটর একক প্যারামিটারে সীমাবদ্ধ নয়। () অপারেটর যেকোন সংখ্যক পরামিতি নিতে পারে। অন্যদিকে ইউনারী অপারেটরগুলির কোনও পরামিতি থাকতে পারে না।
চার্লস সালভিয়া


উত্তর:


148

আপনি যদি নিজের অপারেটরকে ওভারলোড হওয়া ফাংশনটিকে সদস্য ফাংশন হিসাবে সংজ্ঞায়িত করেন, তবে সংকলকটি এর মতো এক্সপ্রেশনগুলি অনুবাদ s1 + s2করে s1.operator+(s2)তার মানে, অপারেটর ওভারলোডেড সদস্য ফাংশনটি প্রথম অপরেন্ডে আমন্ত্রণ জানায়। সদস্য ফাংশন এভাবেই কাজ করে!

তবে প্রথম অপারেন্ড যদি ক্লাস না হয়? একটি বড় সমস্যা আছে যদি আমরা কোনও অপারেটরকে ওভারলোড করতে চাই যেখানে প্রথম অপারেন্ডটি কোনও শ্রেণির ধরণ নয়, বরং বলুন doubleসুতরাং আপনি এই মত লিখতে পারবেন না 10.0 + s2। তবে আপনি মত প্রকাশের জন্য অপারেটরকে ওভারলোডেড সদস্য ফাংশন লিখতে পারেন s1 + 10.0

এই ক্রম সমস্যাটি সমাধান করতে আমরা অপারেটরকে ওভারলোডেড ফাংশনটি সংজ্ঞায়িত করি friendযদি এটির privateসদস্যদের অ্যাক্সেস করার প্রয়োজন হয় । যখন ব্যক্তিগত সদস্যদের অ্যাক্সেস করার প্রয়োজন হয় তখনই এটি তৈরি করুন friendঅন্যথায় কেবল এটি এনক্যাপসুলেশন উন্নত করতে অ-বন্ধুহীন অ-সদস্যের ফাংশন তৈরি করুন !

class Sample
{
 public:
    Sample operator + (const Sample& op2); //works with s1 + s2
    Sample operator + (double op2); //works with s1 + 10.0

   //Make it `friend` only when it needs to access private members. 
   //Otherwise simply make it **non-friend non-member** function.
    friend Sample operator + (double op1, const Sample& op2); //works with 10.0 + s2
}

এগুলি পড়ুন:
অপারেন্ডগুলিতে অর্ডার দেওয়ার ক্ষেত্রে একটি সামান্য সমস্যা কীভাবে সদস্যবিহীন ক্রিয়াকলাপগুলি
এনক্যাপসুলেশন উন্নত করে


2
" friendব্যক্তিগত সদস্যদের অ্যাক্সেস করার প্রয়োজন হলেই এটি তৈরি
করুন..আপনি যখন লেখকগণের

4
@ অভী: আপনার চয়ন চয়ন করুন: উন্নত এনক্যাপসুলেশন বনাম অলস লেখার অভ্যাস!
নওয়াজ

6
@ মথিয়াস, সমস্ত অপারেটর চলাচলকারী নয়। সাধারণ উদাহরণটি হ'ল a/b
এডিএ-কিএ মার্ট-ওরা-ই

3
আপনার অ-সদস্য অপারেটরদের প্রয়োজনীয়তা তৈরি এড়ানোর একটি সাধারণ উপায় friendহ'ল অপারেশন-অ্যাসাইনমেন্ট অপারেটরগুলির শর্তাবলী এগুলি প্রয়োগ করা (যা প্রায় অবশ্যই জনসাধারণের সদস্য হবে)। উদাহরণস্বরূপ, আপনি T T::operator+=(const T &rhs)সদস্য T operator(T lhs, const T &rhs)হিসাবে সংজ্ঞা দিতে এবং তারপরে অ-সদস্য হিসাবে সংজ্ঞা দিতে পারেন return lhs += rhs;। অ-সদস্য ফাংশনটি শ্রেণীর মতো একই নামস্থানে সংজ্ঞায়িত করা উচিত।
অ্যাড্রিয়ান ম্যাকার্থি

2
@ ক্রিকি: তবে lhs যদি একটি অনুলিপি হয় (যেমন এটি আমার মন্তব্যে রয়েছে), তবে LHS পরিবর্তিত হওয়ার বিষয়টি কোন বিষয় নয়।
অ্যাড্রিয়ান ম্যাকার্থি

20

এটি friendঅপারেটর ওভারলোডস এবং সদস্য ফাংশন অপারেটর ওভারলোডগুলির মধ্যে পার্থক্য নয় কারণ এটি গ্লোবাল অপারেটর ওভারলোড এবং সদস্য ফাংশন অপারেটর ওভারলোডের মধ্যে রয়েছে।

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

Foo f = 100;
int x = 10;
cout << x + f;

এটি কেবল তখনই কাজ করে যদি কোনও গ্লোবাল অপারেটর ওভারলোড থাকে

ফু অপারেটর + (ইনট এক্স, কনট ফু & চ);

নোট করুন যে গ্লোবাল অপারেটর ওভারলোডের প্রয়োজনীয়ভাবে কোনও friendফাংশন হওয়ার দরকার নেই । এটি কেবল তখনই প্রয়োজন যখন এর ব্যক্তিগত সদস্যদের অ্যাক্সেসের প্রয়োজন হয় Foo, তবে এটি সবসময় হয় না।

নির্বিশেষে, যদি Fooকেবল সদস্য ফাংশন অপারেটর ওভারলোড থাকে তবে:

class Foo
{
  ...
  Foo operator + (int x);
  ...
};

... তবে আমরা কেবল তখনই ভাব প্রকাশ করতে সক্ষম হব যেখানে প্লাস অপারেটরের বামে একটি Fooউদাহরণ উপস্থিত হয় ।


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