c++ উনল কখন আপনি সি++ এ 'বন্ধুর' ব্যবহার করবেন?




সি++ প্রোগ্রামিং বই ডাউনলোড (24)

আমি সি ++ এফএকিউ এর মাধ্যমে পড়তেছি এবং friend ঘোষণার বিষয়ে অদ্ভুত ছিলাম। আমি ব্যক্তিগতভাবে এটি ব্যবহার করা হয়নি, তবে আমি ভাষা অনুসন্ধান করতে আগ্রহী।

friend ব্যবহার করার একটি ভাল উদাহরণ কি?

প্রায়শই জিজ্ঞাসা করা প্রশ্নাবলীটি একটু বেশি << >> অপারেটর ওভারলোডিং এবং সেই ক্লাসগুলির বন্ধু হিসেবে যুক্ত করার ধারণাটি পছন্দ করি। তবে আমি কিভাবে encapsulation বিরতি না নিশ্চিত না। কখন এই ব্যতিক্রমগুলি OOP এর কঠোরতার মধ্যে থাকতে পারে?


বন্ধু ফাংশন এবং ক্লাস সাধারণ ক্ষেত্রে ব্রেকিং ইনકેપসুলেশন এড়াতে ক্লাসের ব্যক্তিগত এবং সুরক্ষিত সদস্যদের সরাসরি অ্যাক্সেস প্রদান করে। সর্বাধিক ব্যবহার ostream সঙ্গে: আমরা টাইপ করতে সক্ষম হতে চাই:

Point p;
cout << p;

যাইহোক, এইটিকে পয়েন্টের ব্যক্তিগত তথ্য অ্যাক্সেসের প্রয়োজন হতে পারে, তাই আমরা ওভারলোড হওয়া অপারেটরটি সংজ্ঞায়িত করি

friend ostream& operator<<(ostream& output, const Point& p);

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

আপনি যদি বন্ধুকে ক্লাসের এক্সটেনশান হিসাবে দেখেন তবে তা ইস্যু নয়, যৌক্তিকভাবে কথা বলা। কিন্তু, সেই ক্ষেত্রে, কেন প্রথমে বন্ধুকে ভাড়া করা দরকার?

'বন্ধু' অর্জনের একই জিনিসটি অর্জন করতে, কিন্তু এনক্যাপুলেশন ভেঙ্গে না থাকলে, এটি করতে পারেন:

class A
{
public:
    void need_your_data(B & myBuddy)
    {
        myBuddy.take_this_name(name_);
    }
private:
    string name_;
};

class B
{
public:
    void print_buddy_name(A & myBuddy)
    {
        myBuddy.need_your_data(*this);
    }
    void take_this_name(const string & name)
    {
        cout << name;
    }
}; 

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

আমি মনে করি 'বন্ধু' ব্যবহার করে কেবল বিতর্কিত সুবিধার সাথে একটি শর্টকাট, তবে নির্দিষ্ট খরচ।


সংক্ষিপ্ত উত্তর হবে: এটি আসলে encapsulation উন্নত যখন বন্ধু ব্যবহার করুন। পঠনযোগ্যতা এবং ব্যবহারযোগ্যতা উন্নতি (অপারেটর << এবং >> ক্যানোনিকাল উদাহরণ) এছাড়াও একটি ভাল কারণ।

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


অপারেটর << এবং অপারেটরের সাথে সম্পর্কিত >> এই অপারেটরদের বন্ধু তৈরি করার কোনও কারণ নেই। এটা সত্য যে তারা সদস্যের কাজ না হওয়া উচিত, তবে তাদের বন্ধু হতে হবে না।

করতে ভাল জিনিস হল পাবলিক মুদ্রণ (ostream &) তৈরি করুন এবং পড়া (আইটি্রিম এবং) ফাংশন। তারপরে, সেই ফাংশনের শর্তে অপারেটর << এবং অপারেটর >> লিখুন। এটি আপনাকে সেই ফাংশনগুলি ভার্চুয়াল করতে সক্ষম করার অতিরিক্ত যোগফল দেয়, যা ভার্চুয়াল সিরিয়ালাইজেশন সরবরাহ করে।


Singleton ক্লাস তৈরি করার সময় আমি একটি friend ব্যবহার যেখানে একটি নির্দিষ্ট উদাহরণ। friend শব্দটি আমাকে অ্যাক্সেসার ফাংশন তৈরি করতে দেয়, যা ক্লাসে "GetInstance ()" পদ্ধতির চেয়ে আরও সংক্ষিপ্ত।

/////////////////////////
// Header file
class MySingleton
{
private:
    // Private c-tor for Singleton pattern
    MySingleton() {}

    friend MySingleton& GetMySingleton();
}

// Accessor function - less verbose than having a "GetInstance()"
//   static function on the class
MySingleton& GetMySingleton();


/////////////////////////
// Implementation file
MySingleton& GetMySingleton()
{
    static MySingleton theInstance;
    return theInstance;
}

প্রথমতঃ (আইএমও) friend বলে না যে friend দরকারী না। এটা কার্যকরী. অনেক ক্ষেত্রে আপনার কাছে এমন তথ্য বা কার্যকারিতা রয়েছে যা সর্বজনীনভাবে উপলভ্য হওয়ার উদ্দেশ্যে নয়। এটি বিশেষ করে বড় কোডবেসগুলির সাথে সত্যিকারের সত্য যা অনেক লেখক যাদের কেবলমাত্র বিভিন্ন এলাকার সাথে পরিচিত হতে পারে।

বন্ধু স্পেসিফায়ারের বিকল্প আছে তবে প্রায়ই তারা কষ্টকর (সিপিপি-লেভেল কংক্রিট ক্লাস / মাস্কেড টাইপডফ) বা বোকামিহীন নয় (মন্তব্য বা ফাংশন নাম কনভেনশনগুলি)।

উত্তর উপর;

friend স্পেসিফিকেশন শ্রেণিবদ্ধ শ্রেণির অ্যাক্সেসকে সুরক্ষিত ডেটা বা বন্ধুত্বের বিবৃতি তৈরি করে শ্রেণির মধ্যে কার্যকারিতা অ্যাক্সেস করতে দেয়। উদাহরণস্বরূপ নীচের কোডে কেউ কেউ তাদের নামের জন্য একটি শিশুকে জিজ্ঞাসা করতে পারে, কিন্তু শুধুমাত্র মা এবং শিশু নামটি পরিবর্তন করতে পারে।

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

class Child
{
//Mother class members can access the private parts of class Child.
friend class Mother;

public:

  string name( void );

protected:

  void setName( string newName );
};

ক্যানোনিকাল উদাহরণটি ওভারলোড অপারেটর <<। আরেকটি সাধারণ ব্যবহার হেল্পার বা অ্যাডমিন ক্লাসকে আপনার অভ্যন্তরীণগুলিতে অ্যাক্সেস করার অনুমতি দেয়।

এখানে সি ++ বন্ধুদের সম্পর্কে শুনেছি এমন কয়েকটি নির্দেশিকা রয়েছে। শেষ এক বিশেষভাবে স্মরণীয়।

  • আপনার বন্ধুরা আপনার সন্তানের বন্ধু না।
  • আপনার সন্তানের বন্ধু আপনার বন্ধু হয় না।
  • শুধুমাত্র বন্ধু আপনার ব্যক্তিগত অংশ স্পর্শ করতে পারেন।

আপনি ব্যক্তিগত / সুরক্ষিত / সর্বজনীন অধিকার ব্যবহার করে সদস্যদের এবং ফাংশনের অ্যাক্সেস অধিকারগুলি নিয়ন্ত্রণ করেন? তাই প্রতিটি 3 স্তরের প্রতিটির ধারণাটি স্পষ্টভাবে অনুমান করা, তাহলে এটি পরিষ্কার হওয়া উচিত যে আমরা কিছু হারিয়েছি ...

উদাহরণ হিসাবে সুরক্ষিত হিসাবে সদস্য / ফাংশন ঘোষণা চমত্কার জেনেরিক। আপনি বলছেন যে এই ফাংশন সবার জন্য নাগালের বাইরে (অবশ্যই উত্তরাধিকারসূত্রে প্রাপ্ত সন্তানের বাদে)। কিন্তু ব্যতিক্রম সম্পর্কে কি? প্রতিটি নিরাপত্তা ব্যবস্থা আপনাকে কিছু ধরনের 'সাদা তালিকা' অধিকার করতে দেয়?

তাই বন্ধু আপনাকে রক কঠিন বস্তু বিচ্ছিন্নতা থাকার নমনীয়তা দেয়, তবে আপনি যা মনে করেন সেগুলির জন্য একটি "লোফোল" তৈরি করতে পারবেন।

আমি অনুমান করি যে এটির প্রয়োজন নেই কারণ এটি এমন কোনও নকশা যা সর্বদা এটি ছাড়াই করবে। আমি মনে করি এটি বৈশ্বিক ভেরিয়েবলগুলির আলোচনার মতোই: আপনি তাদের কখনই ব্যবহার করতে পারবেন না, তাদের ছাড়া করার উপায় সর্বদা আছে ... কিন্তু বাস্তবে, আপনি এমন ঘটনাগুলি দেখেন যেখানে এটি প্রায় (প্রায়) সবচেয়ে মার্জিত উপায় হয়ে থাকে। .. আমি মনে করি বন্ধুদের সাথে একই ঘটনা।

এটি কোনও ভাল কাজ করে না, অন্যথায় আপনি একটি সেটিং ফাংশন ব্যবহার না করে সদস্যের পরিবর্তনশীল অ্যাক্সেস করতে দেয়

ভাল এটি তাকান ঠিক উপায় নয়। ধারণাটি হ'ল WHO কী অ্যাক্সেস করতে পারে, কোন সেটিং ফাংশনটি এর সাথে সামান্য কিছু করার আছে না তা নিয়ন্ত্রণ করতে হয়।


গাছ উদাহরণটি একটি সুন্দর উদাহরণ: একটি উত্তরাধিকার সম্পর্ক ছাড়া কিছু ভিন্ন শ্রেণীতে প্রয়োগ করা একটি বস্তু থাকার।

সম্ভবত আপনি এটির জন্য একটি কনস্ট্রাক্টর সুরক্ষিত রাখতে এবং আপনার "বন্ধু" কারখানার ব্যবহার করতে বাধ্য করতে পারেন।

ঠিক আছে, ঠিক আছে, আপনি এটা ছাড়া বাঁচতে পারেন।


আরেকটি ব্যবহার: বন্ধু (+ ভার্চুয়াল উত্তরাধিকার) একটি বর্গ থেকে প্রাপ্তি এড়াতে ব্যবহার করা যেতে পারে (উর: "একটি বর্গ কমিয়ে আনা") => 1 , 2

2 থেকে:

 class Fred;

 class FredBase {
 private:
   friend class Fred;
   FredBase() { }
 };

 class Fred : private virtual FredBase {
 public:
   ...
 }; 

বিভিন্ন শ্রেণীর (অন্যের কাছ থেকে উত্তরাধিকারসূত্রে প্রাপ্ত নয়) অন্য শ্রেণীতে ব্যক্তিগত বা সুরক্ষিত সদস্যদের ব্যবহার করার সময় আপনি বন্ধুত্ব ব্যবহার করতে পারেন।

বন্ধু ফাংশনগুলির সাধারণ ব্যবহারের ক্ষেত্রে উভয় প্রাইভেট বা সুরক্ষিত সদস্যদের অ্যাক্সেস করা দুটি পৃথক ক্লাসের মধ্যে পরিচালিত হয় অপারেশন।

http://www.cplusplus.com/doc/tutorial/inheritance/ থেকে ।

আপনি এই উদাহরণটি দেখতে পারেন যেখানে সদস্যহীন পদ্ধতিটি ক্লাসের ব্যক্তিগত সদস্যদের অ্যাক্সেস করে। ক্লাসের বন্ধু হিসেবে এই ক্লাসে এই পদ্ধতিটি ঘোষণা করতে হবে।

// friend functions
#include <iostream>
using namespace std;

class Rectangle {
    int width, height;
  public:
    Rectangle() {}
    Rectangle (int x, int y) : width(x), height(y) {}
    int area() {return width * height;}
    friend Rectangle duplicate (const Rectangle&);
};

Rectangle duplicate (const Rectangle& param)
{
  Rectangle res;
  res.width = param.width*2;
  res.height = param.height*2;
  return res;
}

int main () {
  Rectangle foo;
  Rectangle bar (2,3);
  foo = duplicate (bar);
  cout << foo.area() << '\n';
  return 0;
}

যখন আপনি একটি কন্টেইনার তৈরি করেন তখন বন্ধু সহজে আসে এবং আপনি সেই ক্লাসের জন্য একটি ইটারারেটর বাস্তবায়ন করতে চান।


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

         Game
        /    \
 TwoPlayer  SinglePlayer

এই সব ক্লাসের কাঠামো অংশ এবং আমাদের দলের দ্বারা রক্ষণাবেক্ষণ ছিল। কোম্পানির তৈরি গেমগুলি গেমসের শিশুদের একটিতে প্রাপ্ত এই ফ্রেমওয়ার্কের উপরে নির্মিত হয়েছিল। ইস্যু ছিল যে গেমটি বিভিন্ন জিনিসের ইন্টারফেস ছিল যা SinglePlayer এবং TwoPlayer অ্যাক্সেসের প্রয়োজন ছিল কিন্তু আমরা ফ্রেমওয়ার্ক ক্লাসগুলির বাইরে প্রকাশ করতে চাইনি। সমাধানটি সেই ইন্টারফেসগুলিকে ব্যক্তিগত করে তুলতে এবং বন্ধুত্বের মাধ্যমে টুপ্লেয়ার এবং একক প্লেয়ার অ্যাক্সেসের অনুমতি দেয়।

সত্যই এই সমগ্র ইস্যুটি আমাদের সিস্টেমের আরও ভাল বাস্তবায়ন দ্বারা সমাধান করা যেতে পারে তবে আমাদের যা ছিল তা আমরা বন্ধ হয়ে গিয়েছিলাম।


আপনি যখন friend শব্দটি ব্যবহার করেন এবং / অথবা আপনার সম্পর্কে খুব সতর্কতা অবলম্বন করতে হবে, এবং আপনার মত আমি খুব কমই এটি ব্যবহার করেছি। নীচে friend এবং বিকল্প ব্যবহার করে কিছু নোট হয়।

আসুন বলুন আপনি দুটি বস্তুর তুলনা করতে চান কিনা তা দেখতে সমান। আপনি হয়:

  • তুলনা করার জন্য অ্যাক্সেসার পদ্ধতি ব্যবহার করুন (প্রতিটি ivar চেক এবং সমতা নির্ধারণ)।
  • অথবা, আপনি সরাসরি তাদের জনসাধারণের দ্বারা সব সদস্যদের অ্যাক্সেস করতে পারে।

প্রথম বিকল্পটি নিয়ে সমস্যাটি হল এটি অ্যাক্সেসারগুলির একটি লট হতে পারে যা সরাসরি পরিবর্তনযোগ্য অ্যাক্সেসের চেয়ে সামান্য (ধীর) ধীরে ধীরে পড়তে কঠিন, এবং গুরুতর। দ্বিতীয় পদ্ধতির সাথে সমস্যা হল যে আপনি সম্পূর্ণরূপে encapsulation বিরতি।

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

class Beer {
public:
    friend bool equal(Beer a, Beer b);
private:
    // ...
};

পদ্ধতিটি equal(Beer, Beer) এখন b এবং b এর ব্যক্তিগত সদস্যদের সরাসরি অ্যাক্সেস রয়েছে (যা char *brand , float percentAlcohol ইত্যাদি হতে পারে।) এটি একটি পরিবর্তিত উদাহরণ, আপনি শীঘ্রই একটি ওভারলোড করা friend কাছে আবেদন করবেন == operator , কিন্তু আমরা যে পেতে হবে।

কিছু জিনিস মনে রাখবেন:

  • একটি friend ক্লাস সদস্য সদস্য হয় না
  • এটি ক্লাসের ব্যক্তিগত সদস্যদের বিশেষ অ্যাক্সেসের সাথে একটি সাধারণ ফাংশন
  • সকল অ্যাক্সেসর এবং মিউটেটরকে বন্ধুদের সাথে প্রতিস্থাপন করবেন না (আপনি সর্বদাই সবকিছু public তুলতে পারেন!)
  • বন্ধুত্ব পারস্পরিক হয় না
  • বন্ধুত্ব সংগ্রাহক হয় না
  • বন্ধুত্ব উত্তরাধিকারসূত্রে প্রাপ্ত হয় না
  • অথবা, সি ++ প্রশ্নাবলী ব্যাখ্যা করে : "আমি আপনাকে আমার বন্ধুত্বের অ্যাক্সেস দেওয়ার কারণে স্বয়ংক্রিয়ভাবে আমার বাচ্চাদের অ্যাক্সেস দেয় না, স্বয়ংক্রিয়ভাবে আপনার বন্ধুদের অ্যাক্সেস দেয় না এবং স্বয়ংক্রিয়ভাবে আমাকে অ্যাক্সেস দেয় না । "

অন্য উপায়টি করার ক্ষেত্রে এটি কঠিন হয়ে গেলে আমি শুধুমাত্র friends ব্যবহার করি। অন্য উদাহরণ হিসাবে, অনেক ভেক্টর গণিত ফাংশনগুলি প্রায়ই Mat2x2 , Mat3x3 , Mat4x4 , Vec2 , Vec3 , Vec4 ইত্যাদির Vec4 কারণে friends হিসাবে তৈরি হয় এবং এটি সর্বত্র অ্যাক্সেসার ব্যবহার করার পরিবর্তে বন্ধুদের পক্ষে এত সহজ। হিসাবে নির্দেশিত, << (সত্যিই ডিবাগিং জন্য সহজ), >> এবং সম্ভবত == অপারেটর প্রয়োগ করা হলে friend প্রায়ই দরকারী, কিন্তু এই মত কিছু জন্য ব্যবহার করা যেতে পারে:

class Birds {
public:
    friend Birds operator +(Birds, Birds);
private:
    int numberInFlock;
};


Birds operator +(Birds b1, Birds b2) {
    Birds temp;
    temp.numberInFlock = b1.numberInFlock + b2.numberInFlock;
    return temp;
}

আমি যেমন বলি, আমি friend প্রায়ই খুব বেশি ব্যবহার করি না, কিন্তু এখনই এবং তারপর এটি আপনার যা দরকার তা। আশাকরি এটা সাহায্য করবে!


কর্মক্ষেত্রে আমরা ব্যাপকভাবে পরীক্ষার কোডের জন্য বন্ধুদের ব্যবহার করি। এর অর্থ হল আমরা প্রধান অ্যাপ্লিকেশন কোডের জন্য লুকানো সঠিক এনক্যাপুলেশন এবং তথ্য সরবরাহ করতে পারি। কিন্তু আমরা পরীক্ষার জন্য অভ্যন্তরীণ রাষ্ট্র এবং তথ্য পরিদর্শন করতে বন্ধুদের ব্যবহার করে পৃথক পরীক্ষা কোড থাকতে পারে।

বলার অপেক্ষা রাখে না আমি আপনার নকশা একটি অপরিহার্য উপাদান হিসাবে বন্ধু শব্দ ব্যবহার করবেন না।


ক্লাসের জন্য গাছের অ্যালগরিদম বাস্তবায়ন করার সময় ফ্রেমওয়ার্ক কোডটি আমাদেরকে নোড বর্গের বন্ধু হিসেবে গাছের বর্গ হিসাবে সরবরাহ করেছিল।

এটি কোনও ভাল কাজ করে না, অন্যথায় আপনি একটি সেটিং ফাংশন ব্যবহার না করে সদস্যের পরিবর্তনশীল অ্যাক্সেস করতে দেয়।


বন্ধু কলব্যাক জন্য দরকারী। আপনি স্ট্যাটিক পদ্ধতি হিসাবে callbacks বাস্তবায়ন করতে পারে

class MyFoo
{
private:
    static void callback(void * data, void * clientData);
    void localCallback();
    ...
};

যেখানে অভ্যন্তরীণ callbackকল localCallback, এবং clientDataএটি আপনার দৃষ্টান্ত আছে। আমার মতে,

বা ...

class MyFoo
{
    friend void callback(void * data, void * callData);
    void localCallback();
}

এইটি কীভাবে সি-পি-স্টাইল ফাংশন হিসাবে সিপিএ-তে সংজ্ঞায়িত করা যায় এবং ক্লাসটিকে বিভক্ত করে না।

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

হেডারের মধ্যে:

class MyFooPrivate;
class MyFoo
{
    friend class MyFooPrivate;
public:
    MyFoo();
    // Public stuff
private:
    MyFooPrivate _private;
    // Other private members as needed
};

সিপিপি,

class MyFooPrivate
{
public:
   MyFoo *owner;
   // Your complexity here
};

MyFoo::MyFoo()
{
    this->_private->owner = this;
}

ডাউনস্ট্রীম এই ভাবে দেখতে হবে না যে জিনিস লুকাতে সহজ হয়ে যায়।


TDD অনেক বার করতে আমি C ++ এ 'বন্ধুর' শব্দটি ব্যবহার করেছি।

একজন বন্ধু আমার সম্পর্কে সবকিছু জানেন?

আপডেট করা হয়েছে: আমি Bjarne Stroustrup সাইট থেকে "বন্ধু" শব্দ সম্পর্কে এই মূল্যবান উত্তর খুঁজে পেয়েছি।

"ফ্রেন্ড" অ্যাক্সেস দেওয়ার জন্য একটি স্পষ্ট প্রক্রিয়া, যেমন সদস্যতা।


আমি বন্ধু প্রবেশাধিকার ব্যবহার করার জন্য সহজ জায়গা খুঁজে পেয়েছি: ব্যক্তিগত ফাংশন ইউনিটস্টেস্ট।


সি ++ এর নির্মাতা বলছেন যে কোনও এনক্যাপুলেশন নীতি নকল করছে না এবং আমি তাকে উদ্ধৃত করবো:

"বন্ধু" encapsulation লঙ্ঘন করে? না। এটা না। "ফ্রেন্ড" অ্যাক্সেস দেওয়ার জন্য একটি স্পষ্ট প্রক্রিয়া, যেমন সদস্যতা। আপনি (একটি স্ট্যান্ডার্ড কনফর্মিং প্রোগ্রামে) নিজের উত্সটি সংশোধন না করে নিজেকে শ্রেণীতে অ্যাক্সেস করতে পারবেন।

স্পষ্ট বেশী ...


বন্ধু ঘোষণা জন্য রেফারেন্স হিসাবে বলেছেন:

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

তাই শুধু একটি অনুস্মারক হিসাবে, উত্তর কিছু প্রযুক্তিগত ত্রুটি আছে যা বলে যে friendশুধুমাত্র সুরক্ষিত সদস্যদের পরিদর্শন করতে পারেন ।


friend শব্দ একটি ভাল ব্যবহার সংখ্যা আছে। এখানে দুটি ব্যবহার অবিলম্বে আমার কাছে দৃশ্যমান:

বন্ধু সংজ্ঞা

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

namespace utils {
    class f {
    private:
        typedef int int_type;
        int_type value;

    public:
        // let's assume it doesn't only need .value, but some
        // internal stuff.
        friend f operator+(f const& a, f const& b) {
            // name resolution finds names in class-scope. 
            // int_type is visible here.
            return f(a.value + b.value);
        }

        int getValue() const { return value; }
    };
}

int main() {
    utils::f a, b;
    std::cout << (a + b).getValue(); // valid
}

ব্যক্তিগত সিআরটিপি বেস ক্লাস

কখনও কখনও, আপনি একটি পলিসি প্রাপ্ত হওয়া শ্রেণিতে অ্যাক্সেস প্রয়োজন প্রয়োজন খুঁজে পেতে:

// possible policy used for flexible-class.
template<typename Derived>
struct Policy {
    void doSomething() {
        // casting this to Derived* requires us to see that we are a 
        // base-class of Derived.
        some_type const& t = static_cast<Derived*>(this)->getSomething();
    }
};

// note, derived privately
template<template<typename> class SomePolicy>
struct FlexibleClass : private SomePolicy<FlexibleClass> {
    // we derive privately, so the base-class wouldn't notice that, 
    // (even though it's the base itself!), so we need a friend declaration
    // to make the base a friend of us.
    friend class SomePolicy<FlexibleClass>;

    void doStuff() {
         // calls doSomething of the policy
         this->doSomething();
    }

    // will return useful information
    some_type getSomething();
};

আপনি this উত্তর যে জন্য একটি অনির্ধারিত উদাহরণ পাবেন। this উত্তর ব্যবহার করে অন্য কোড। ডাটা-সদস্য-পয়েন্টারগুলি ব্যবহার করে প্রাপ্ত শ্রেণির ডাটা-ক্ষেত্রগুলি অ্যাক্সেস করতে সক্ষম হওয়ার জন্য সিআরটিপি বেসটি এই পয়েন্টারটিকে ধারণ করে।


TDD অনেক বার করতে আমি C ++ এ 'বন্ধুর' শব্দটি ব্যবহার করেছি।
একজন বন্ধু আমার সম্পর্কে সবকিছু জানেন?

না, এর একমাত্র উপায় বন্ধুত্ব: `(


অ্যান্ড্রু এর উদাহরণ আরেকটি সাধারণ সংস্করণ, ভয়ঙ্কর কোড-দম্পতি

parent.addChild(child);
child.setParent(parent);

উভয় লাইনগুলি সর্বদা একসাথে করা এবং সামঞ্জস্যপূর্ণ ক্রমে যদি আপনি চিন্তাধারাগুলি ব্যক্তিগত করে তুলতে পারেন এবং একত্রীকরণ প্রয়োগ করার জন্য একটি বন্ধু ফাংশন করতে পারেন তবে উদ্বেগযুক্ত হওয়ার পরিবর্তে:

class Parent;

class Object {
private:
    void setParent(Parent&);

    friend void addChild(Parent& parent, Object& child);
};

class Parent : public Object {
private:
     void addChild(Object& child);

     friend void addChild(Parent& parent, Object& child);
};

void addChild(Parent& parent, Object& child) {
    if( &parent == &child ){ 
        wetPants(); 
    }
    parent.addChild(child);
    child.setParent(parent);
}

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


@roo : এখানে @roo ভাঙ্গা হয় না কারণ ক্লাস নিজেই নিজের ব্যক্তিগত সদস্যদের অ্যাক্সেস করতে পারে তা নির্ধারণ করে। এনক্যাপুলেশনটি শুধুমাত্র ভাঙ্গা হবে যদি এটি ক্লাসের বাইরে হতে পারে, উদাহরণস্বরূপ যদি আপনার operator << ঘোষণা করে যে "আমি ক্লাস foo বন্ধু।"

private ব্যবহার না করে private ব্যবহারের বদলে friend !

আসলে, সি ++ প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী এই উত্তর







friend