সি ++ তে পলিমারফিজম


129

আমি যতদূর জানি:

সি ++ তিনটি বিভিন্ন ধরণের পলিমারফিজম সরবরাহ করে।

  • ভার্চুয়াল ফাংশন
  • ফাংশন নাম ওভারলোডিং
  • অপারেটর ওভারলোডিং

উপরোক্ত তিন ধরণের পলিমারফিজম ছাড়াও অন্যান্য ধরণের বহুকর্ম রয়েছে:

  • রান-টাইম
  • কম্পাইল-টাইম
  • অ্যাড-হক পলিমারফিজম
  • প্যারামেট্রিক পলিমারফিজম

আমি জানি যে রানটাইম পলিমারফিজম ভার্চুয়াল ফাংশন দ্বারা অর্জন করা যেতে পারে এবং স্ট্যাটিক পলিমারফিজম টেম্পলেট ফাংশন দ্বারা অর্জন করা যেতে পারে

তবে অন্য দুজনের জন্য

অ্যাডহক বহুবর্ষ:

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

প্যারামেট্রিক বহুবর্ষ:

যদি সমস্ত কোড কোনও নির্দিষ্ট ধরণের উল্লেখ ছাড়াই লিখিত হয় এবং এভাবে কোনও নতুন সংখ্যার সাথে স্বচ্ছভাবে ব্যবহার করা যায় তবে একে প্যারামেট্রিক পলিমারফিজম বলে ism

আমি এগুলি খুব কমই বুঝতে পারি :(

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


30
প্রকৃতপক্ষে, সি ++ এর চার ধরণের পলিমারফিজম রয়েছে: প্যারাম্যাট্রিক (সি ++ তে টেমপ্লেটগুলির মাধ্যমে উদারতা), অন্তর্ভুক্তি (সি ++ তে ভার্চুয়াল পদ্ধতিগুলির মাধ্যমে সাব-টাইপিং), ওভারলোডিং এবং জবরদস্তি (অন্তর্নিহিত রূপান্তর)। ধারণামূলকভাবে, ফাংশন ওভারলোডিং এবং অপারেটর ওভারলোডিংয়ের মধ্যে সামান্য পার্থক্য রয়েছে।
ফ্রেডওভারফ্লো

সুতরাং দেখে মনে হচ্ছে যে আমি উল্লিখিত ওয়েবসাইটগুলি অনেককে বিভ্রান্ত করছে..আমি কি সঠিক?
বিজয়

@ জম্বি: সেই ওয়েবসাইটটি প্রচুর ভাল ধারণার উপর স্পর্শ করেছে, তবে এটি পরিভাষা ব্যবহারে যথাযথ এবং সামঞ্জস্যপূর্ণ নয় (উদাহরণস্বরূপ, একবার এটি ভার্চুয়াল প্রেরণ / রানটাইম পলিমারফিজম সম্পর্কে কথা বলা শুরু করলে, এটি বহুবর্ষ সম্পর্কে বহু বক্তব্য দেয় যা ভুল সাধারণভাবে তবে ভার্চুয়াল প্রেরণের জন্য সত্য)। আপনি যদি ইতিমধ্যে বিষয়টি বুঝতে পেরেছেন তবে যা বলা হচ্ছে তার সাথে আপনি সম্পর্কিত করতে পারেন এবং মানসিকভাবে প্রয়োজনীয় সতর্কতাগুলি সন্নিবেশ করতে পারেন, তবে সাইটটি পড়ে সেখানে পৌঁছনো কঠিন ....
টনি ডেলরয়

কিছু পদগুলি কাছাকাছি-সমার্থক শব্দ বা আরও বেশি সম্পর্কিত তবে অন্যান্য শর্তের চেয়ে আরও সীমিত। উদাহরণস্বরূপ, "অ্যাড-হক পলিমারফিজম" শব্দটি বেশিরভাগ ক্ষেত্রে আমার অভিজ্ঞতায় হাস্কেলে ব্যবহৃত হয়, তবুও "ভার্চুয়াল ফাংশন" খুব ঘনিষ্ঠভাবে সম্পর্কিত। গৌণতম পার্থক্য হ'ল "ভার্চুয়াল ফাংশন" হ'ল একটি অবজেক্ট-ওরিয়েন্টেড শব্দ যা "লেট বাইন্ডিং" সহ সদস্য ফাংশনকে বোঝায়। "একাধিক প্রেরণ" হ'ল এক ধরণের অ্যাড-হক পলিমারফিজম। এবং ফ্রেডওভারফ্লো যেমন বলেছে, অপারেটর এবং ফাংশন ওভারলোডিং উভয়ই মূলত একই জিনিস।
স্টিভ 314

আমি আপনার জন্য আপনার ফর্ম্যাটিং স্থির করেছি। সম্পাদনা ফলকের ডানদিকে উপলব্ধ সহায়তাটি পড়ুন। > 200 প্রশ্ন এবং> 3 কে সহ কারও এই প্রাথমিক জিনিসটি জানা উচিত। এছাড়াও, আপনি একটি নতুন কীবোর্ড কিনতে চাইতে পারেন। মনে হচ্ছে এটির শিফট কীটি মাঝেমধ্যে ব্যর্থ হচ্ছে। ওহ, এবং: সি ++ তে "টেম্পলেট ফাংশন" বলে কোনও জিনিস নেইফাংশন টেম্পলেট আছে, তবে ।
এসবিআই

উত্তর:


219

পলিমারফিজমের জন্য / প্রয়োজনীয়তাগুলি বোঝা

পলিমারফিজমটি বোঝার জন্য - যেহেতু শব্দটি কম্পিউটিং সায়েন্সে ব্যবহৃত হয় - এটি এর সাধারণ ব্যাখ্যা এবং এর সংজ্ঞা থেকে শুরু করতে সহায়তা করে। বিবেচনা:

    Type1 x;
    Type2 y;

    f(x);
    f(y);

এখানে f()কিছু অপারেশন করা এবং মান xএবং yইনপুট হিসাবে দেওয়া হচ্ছে ।

পলিমারফিজম প্রদর্শন f()করতে , স্বতন্ত্র টাইপ-উপযুক্ত কোড সন্ধান এবং সম্পাদন করতে অবশ্যই কমপক্ষে দুটি স্বতন্ত্র প্রকারের (যেমন intএবং double) মানগুলির সাথে পরিচালনা করতে সক্ষম হতে হবে ।


বহুবর্ষের জন্য সি ++ প্রক্রিয়া +

স্পষ্টত প্রোগ্রামার-নির্দিষ্ট পলিমারফিজম

আপনি এটি লিখতে পারেন f()যে এটি নিম্নলিখিত যে কোনও উপায়ে একাধিক প্রকারে পরিচালনা করতে পারে:

  • প্রাক-প্রক্রিয়াকরণ:

    #define f(X) ((X) += 2)
    // (note: in real code, use a longer uppercase name for a macro!)
  • ওভারলোডিং:

    void f(int& x)    { x += 2; }
    
    void f(double& x) { x += 2; }
  • টেমপ্লেট:

    template <typename T>
    void f(T& x) { x += 2; }
  • ভার্চুয়াল প্রেরণ:

    struct Base { virtual Base& operator+=(int) = 0; };
    
    struct X : Base
    {
        X(int n) : n_(n) { }
        X& operator+=(int n) { n_ += n; return *this; }
        int n_;
    };
    
    struct Y : Base
    {
        Y(double n) : n_(n) { }
        Y& operator+=(int n) { n_ += n; return *this; }
        double n_;
    };
    
    void f(Base& x) { x += 2; } // run-time polymorphic dispatch

অন্যান্য সম্পর্কিত প্রক্রিয়া

অন্তর্নির্মিত ধরণের, স্ট্যান্ডার্ড রূপান্তরগুলি এবং ingালাই / জবরদস্তির জন্য সংকলক দ্বারা সরবরাহিত বহুগুণ সম্পর্কে পরে সম্পূর্ণতার জন্য আলোচনা করা হয়েছে:

  • এগুলি যে কোনওভাবেই স্বজ্ঞাতভাবে বোঝা যায় (" ওহ, সেই " প্রতিক্রিয়াটির নিশ্চয়তা),
  • তারা উপরোক্ত প্রক্রিয়াগুলি এবং প্রয়োজনীয় ব্যবহারের প্রান্তিকতা এবং ব্যবহারে নির্বিঘ্নে প্রভাব ফেলে
  • ব্যাখ্যা আরও গুরুত্বপূর্ণ ধারণা থেকে একটি fidly বিচ্যুতি।

পরিভাষা

আরও শ্রেণিবিন্যাস

উপরের পলিমারফিক পদ্ধতিগুলি দেওয়া, আমরা তাদের বিভিন্ন উপায়ে শ্রেণিবদ্ধ করতে পারি:

  • পলিমারফিক টাইপ-নির্দিষ্ট কোডটি কখন নির্বাচিত হয়?

    • রান টাইম মানে প্রোগ্রামটি চলমান চলাকালীন সমস্ত ধরণের কোড তৈরি করতে হবে এবং রান-টাইমে সঠিক কোডটি নির্বাচিত হয়েছে ( ভার্চুয়াল প্রেরণ )
    • সংকলনের সময় মানে টাইপ-নির্দিষ্ট কোডের পছন্দটি সংকলনের সময় করা হয়। এর পরিণতি: কেবলমাত্র যুক্তিযুক্তর fসাথে উপরে ডাকা একটি প্রোগ্রাম বলুন int- ব্যবহৃত পলিমারফিক পদ্ধতিতে এবং অন্তর্নিহিত পছন্দগুলির উপর নির্ভর করে সংকলকটি কোনও কোড তৈরি করতে এড়াতে পারে f(double), বা উত্পন্ন কোডটি সংকলন বা সংযোগের কোনও সময়ে ফেলে দেওয়া যেতে পারে। ( ভার্চুয়াল প্রেরণ বাদে উপরের সমস্ত প্রক্রিয়া )

  • কোন ধরণের সমর্থিত?

    • অ্যাড-হক অর্থ প্রতিটি প্রকারের সমর্থন করার জন্য আপনি সুস্পষ্ট কোড সরবরাহ করেন (উদাঃ ওভারলোডিং, টেম্পলেট বিশেষীকরণ); আপনি স্পষ্টভাবে "এই" এর জন্য সমর্থন ( অ্যাডহক এর অর্থ অনুসারে) টাইপ, কিছু অন্য "এটি" এবং সম্ভবত "এটি" খুব ;-) যোগ করেন।
    • প্যারামিট্রিক অর্থ আপনি কেবলমাত্র তাদের জন্য সমর্থনটি সক্ষম করার জন্য নির্দিষ্টভাবে কিছু না করে বিভিন্ন প্যারামিটার ধরণের জন্য ফাংশনটি ব্যবহার করার চেষ্টা করতে পারেন (যেমন টেমপ্লেট, ম্যাক্রো)। ফাংশন / অপারেটরদের সঙ্গে একটি বস্তুর টেমপ্লেট / ম্যাক্রো আশা মত আইন করে 1 হয় সব যে সঠিক টাইপ অপ্রাসঙ্গিক হচ্ছে তার কাজ করার টেমপ্লেট / ম্যাক্রো চাহিদা। সি ++ 20 দ্বারা প্রবর্তিত "ধারণাগুলি" প্রকাশ করে এবং এই জাতীয় প্রত্যাশাগুলি প্রয়োগ করে - এখানে cppreferences পৃষ্ঠা দেখুন ।

      • প্যারাম্যাট্রিক পলিমারফিজম হাঁসের টাইপিং সরবরাহ করে - একটি ধারণা জেমস হুইটকম্ব রিলির জন্য দায়ী যা স্পষ্টতই বলেছিল "যখন আমি একটি পাখি দেখতে পাই যা হাঁসের মতো হাঁটছে এবং হাঁসের মতো সাঁতার কাটছে, আমি সেই পাখিকে হাঁস বলি।"

        template <typename Duck>
        void do_ducky_stuff(const Duck& x) { x.walk().swim().quack(); }
        
        do_ducky_stuff(Vilified_Cygnet());
    • সাব টাইপ (ওরফে অন্তর্ভুক্তি) পলিমারফিজম আপনাকে অ্যালগরিদম / ফাংশন আপডেট না করে নতুন ধরণের উপর কাজ করতে দেয় তবে সেগুলি অবশ্যই একই বেস শ্রেণি (ভার্চুয়াল প্রেরণ) থেকে নেওয়া উচিত

1 - টেমপ্লেটগুলি অত্যন্ত নমনীয়। SFINAE (আরও দেখুন std::enable_if) কার্যকরভাবে প্যারামেট্রিক পলিমারফিজমের জন্য বেশ কয়েকটি সেট প্রত্যাশার মঞ্জুরি দেয়। উদাহরণস্বরূপ, আপনি এনকোড করতে পারেন যে আপনি যে ধরণের ডেটা প্রক্রিয়াকরণ করছেন তাতে কোনও .size()সদস্য ব্যবহার করার পরে আপনি একটি ফাংশন ব্যবহার করবেন, অন্যথায় অন্য কোনও ফাংশনটির প্রয়োজন নেই .size()(তবে সম্ভবত কিছুটা ক্ষতিগ্রস্থ হচ্ছে - যেমন ধীর গতিতে ব্যবহার করুন strlen()বা প্রিন্টিং হিসাবে নয় লগতে একটি বার্তা দরকারী)। নির্দিষ্ট পরামিতিগুলির সাথে টেম্পলেটটি ইনস্ট্যান্ট করা হলে আপনি কিছু প্যারামিটারগুলি প্যারামিটারিক ( আংশিক টেম্পলেট বিশেষায়িতকরণ ) না রেখে ( পুরো বিশেষায়িতকরণ ) ছেড়ে দিয়েও অ্যাড-হক আচরণগুলি নির্দিষ্ট করতে পারেন ।

"বহুরুপী"

আলফ স্টেইনবাচ মন্তব্য করেছেন যে সি ++ স্ট্যান্ডার্ড পলিমারফিক কেবল ভার্চুয়াল প্রেরণাদি ব্যবহার করে রান-টাইম পলিমারফিজমকে বোঝায়। জেনারেল কমপ সী। সি ++ স্রষ্টা বাজনার স্ট্রস্ট্রপের গ্লসারি ( http://www.stroustrup.com/glossary.html ) অনুসারে অর্থটি আরও অন্তর্ভুক্ত রয়েছে :

পলিমারফিজম - বিভিন্ন ধরণের সত্তাকে একক ইন্টারফেস সরবরাহ করে। ভার্চুয়াল ফাংশনগুলি একটি বেস ক্লাস দ্বারা সরবরাহিত ইন্টারফেসের মাধ্যমে গতিময় (রান-টাইম) পলিমারফিজম সরবরাহ করে। অতিরিক্ত লোড ফাংশন এবং টেমপ্লেটগুলি স্ট্যাটিক (সংকলন-সময়) পলিমারফিজম সরবরাহ করে। টিসি ++ পিএল 12.2.6, 13.6.1, ডি ও ই 2.9।

এই উত্তর - প্রশ্নের মতো - কম্পের সাথে সি ++ বৈশিষ্ট্য সম্পর্কিত। সী। পরিভাষা।

আলোচনা

সি ++ স্ট্যান্ডার্ড সহ কম্পের চেয়ে "পলিমারফিজম" এর সংকীর্ণ সংজ্ঞা ব্যবহার করে। সী। সম্প্রদায়, আপনার শ্রোতাদের বিবেচনা করে পারস্পরিক বোঝাপড়া নিশ্চিত করার জন্য ...

  • দ্ব্যর্থহীন পরিভাষা ব্যবহার করে ("আমরা কি এই কোডটি অন্য ধরণের জন্য পুনরায় ব্যবহারযোগ্য করতে পারি?" বা "আমরা কি এই কোডটি বহুরূপী করতে পারি?") এর পরিবর্তে, "বা আমরা কি ভার্চুয়াল প্রেরণ ব্যবহার করতে পারি?"), এবং / অথবা
  • পরিষ্কারভাবে আপনার পরিভাষা সংজ্ঞা।

তবুও, দুর্দান্ত সি ++ প্রোগ্রামার হওয়ার পক্ষে কী গুরুত্বপূর্ণ তা বোঝা যাচ্ছে যে পলিমারফিজম আপনার জন্য আসলে কী করছে ...

    আপনাকে একবার "অ্যালগরিদমিক" কোড লিখতে দিন এবং তারপরে এটিকে অনেক ধরণের ডেটাতে প্রয়োগ করতে পারেন

... এবং তারপরে বিভিন্ন পলিমারফিক পদ্ধতিগুলি আপনার প্রকৃত প্রয়োজনগুলির সাথে কীভাবে মেলে সে সম্পর্কে খুব সচেতন হন।

রান-টাইম পলিমারফিজম স্যুট:

  • ইনপুটটি কারখানার পদ্ধতি দ্বারা প্রক্রিয়াজাত করা হয় এবং Base*এস এর মাধ্যমে পরিচালিত ভিন্নজাতীয় বস্তু সংগ্রহ হিসাবে ছড়িয়ে পড়ে ,
  • কনফিগারেশন ফাইল, কমান্ড লাইন সুইচ, ইউআই সেটিংস ইত্যাদির উপর ভিত্তি করে রানটাইম এ নির্বাচন করা বাস্তবায়ন,
  • স্টেট মেশিনের ধরণ হিসাবে রানটাইম সময়ে বাস্তবায়ন বিভিন্ন রকম হয়।

রান-টাইম পলিমারফিজমের জন্য যখন স্পষ্ট ড্রাইভার নেই, তখন কমপাইল-টাইম বিকল্পগুলি প্রায়শই পছন্দনীয়। বিবেচনা:

  • টেম্প্লেটেড ক্লাসগুলির সংকলন-যা-বলা হয় তা রানটাইম ব্যর্থ ফ্যাট ইন্টারফেসের চেয়ে ভাল
  • SFINAE
  • CRTP
  • অপ্টিমাইজেশন (ইনলাইনিং এবং ডেড কোড এলিমিনেশন, লুপ আন্রোলিং, স্ট্যাটিক স্ট্যাক-ভিত্তিক অ্যারে বনাম হিপ সহ অনেকগুলি)
  • __FILE__,, __LINE__স্ট্রিং আক্ষরিক সম্মিলন এবং ম্যাক্রোর অন্যান্য অনন্য ক্ষমতা (যা মন্দ থেকে যায় ;-))
  • টেমপ্লেট এবং ম্যাক্রো পরীক্ষার শব্দার্থিক ব্যবহার সমর্থিত তবে কৃত্রিমভাবে সেই সমর্থন কীভাবে সরবরাহ করা যায় তা সীমাবদ্ধ করবেন না (যেমন ভার্চুয়াল প্রেরণ সদস্যের ফাংশনটির ওভাররাইডগুলির সাথে সঠিকভাবে মিলে যাওয়ার প্রয়োজন হয়)

পলিমারফিজম সমর্থনকারী অন্যান্য প্রক্রিয়া

প্রতিশ্রুতি অনুসারে, সম্পূর্ণতার জন্য বেশ কয়েকটি পেরিফেরিয়াল বিষয়গুলি কভার করা হয়েছে:

  • সংকলক-সরবরাহ ওভারলোড
  • ধর্মান্তর
  • কাস্ট / বলপ্রয়োগ

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

টাইপ-নির্দিষ্ট ক্রিয়াকলাপগুলিতে ম্যাপিংয়ের প্রক্রিয়া

> অন্তর্নিহিত সংকলক-সরবরাহ ওভারলোড

ধারণামূলকভাবে, সংকলক বিল্টিন টাইপের জন্য অনেক অপারেটরকে ওভারলোড করে । এটি ব্যবহারকারী-নির্দিষ্ট ওভারলোডিং থেকে ধারণাগতভাবে পৃথক নয়, তবে এটি সহজেই উপেক্ষা করার কারণে তালিকাবদ্ধ রয়েছে। উদাহরণস্বরূপ, যদি আপনি যোগ করতে পারেন ints এবং doubleএকই স্বরলিপি ব্যবহার র x += 2এবং কম্পাইলার উত্পাদন করে:

  • টাইপ-নির্দিষ্ট সিপিইউ নির্দেশাবলী
  • একই ধরণের ফলাফল।

ওভারলোডিং এর পরে নির্বিঘ্নে ব্যবহারকারী-সংজ্ঞায়িত প্রকারগুলিতে প্রসারিত হয়:

std::string x;
int y = 0;

x += 'c';
y += 'c';

প্রাথমিক ধরণের জন্য সংকলক দ্বারা সরবরাহিত ওভারলোডগুলি উচ্চ-স্তরের (3 জিএল +) কম্পিউটারের ভাষায় প্রচলিত এবং বহুকর্মের স্পষ্ট আলোচনা সাধারণত আরও কিছু বোঝায়। (2 জিএল - সমাবেশের ভাষাগুলি - প্রায়শই প্রোগ্রামারকে বিভিন্ন ধরণের জন্য স্পষ্টভাবে বিভিন্ন মিমোনমিক্স ব্যবহার করতে হয়))

> স্ট্যান্ডার্ড রূপান্তর

সি ++ স্ট্যান্ডার্ডের চতুর্থ বিভাগটি স্ট্যান্ডার্ড রূপান্তরগুলি বর্ণনা করে।

প্রথম পয়েন্টটি সুন্দরভাবে সংক্ষিপ্ত করে (পুরানো খসড়া থেকে - আশা করি এখনও যথেষ্ট পরিমাণে সঠিক):

-1- স্ট্যান্ডার্ড রূপান্তরগুলি অন্তর্নির্মিত ধরণের জন্য সংজ্ঞাযুক্ত অন্তর্নিহিত রূপান্তর। ক্লজ রূপে এই জাতীয় রূপান্তরগুলির পুরো সেটটি গণনা করা হয়। একটি স্ট্যান্ডার্ড রূপান্তর ক্রমটি নিম্নলিখিত ক্রমে মানক রূপান্তরগুলির একটি ক্রম:

  • নিম্নলিখিত সেট থেকে শূন্য বা একটি রূপান্তর: লভ্যালু-থেকে-র্যালুয়ে রূপান্তর, অ্যারে-টু-পয়েন্টার রূপান্তর এবং ফাংশন-টু-পয়েন্টার রূপান্তর।

  • শূন্য বা নিম্নলিখিত রূপ থেকে একটি রূপান্তর: অবিচ্ছেদ্য প্রচার, ভাসমান পয়েন্ট প্রচার, অবিচ্ছেদ্য রূপান্তরগুলি, ভাসমান পয়েন্ট রূপান্তরগুলি, ভাসমান-ইন্টিগ্রাল রূপান্তরগুলি, পয়েন্টার রূপান্তরগুলি, সদস্য রূপান্তরগুলিতে পয়েন্টার এবং বুলিয়ান রূপান্তর।

  • জিরো বা একটি যোগ্যতার রূপান্তর।

[দ্রষ্টব্য: একটি আদর্শ রূপান্তর ক্রমটি খালি থাকতে পারে, অর্থাত্ এতে কোনও রূপান্তর থাকতে পারে না। ] প্রয়োজনীয় গন্তব্য প্রকারে রূপান্তর করার জন্য যদি প্রয়োজন হয় তবে একটি অভিব্যক্তিটির কাছে একটি আদর্শ রূপান্তর ক্রম প্রয়োগ করা হবে।

এই রূপান্তরগুলি কোডের অনুমতি দেয় যেমন:

double a(double x) { return x + 2; }

a(3.14);
a(42);

আগের পরীক্ষা প্রয়োগ করা:

বহুমুখী হতে, [ a()] অবশ্যই কমপক্ষে দুটি স্বতন্ত্র ধরণের (যেমন intএবং double) মানগুলির সাথে পরিচালনা করতে সক্ষম হবে , টাইপ-উপযুক্ত কোডটি সন্ধান এবং সম্পাদন করতে হবে

a()নিজেই কোড বিশেষভাবে চালায় doubleএবং তাই বহুকোষী নয়

কিন্তু, a()সংকলকটির দ্বিতীয় কলটিতে রূপান্তর 42করতে কোনও "ভাসমান পয়েন্ট প্রচার" (স্ট্যান্ডার্ড §4) এর জন্য টাইপ-উপযুক্ত কোড উত্পন্ন করতে জানে 42.0। অতিরিক্ত কোডটি কলিং ফাংশনে রয়েছে। আমরা উপসংহারে এর তাত্পর্য আলোচনা করব।

> জবর, কাস্ট, অন্তর্নিহিত নির্মাতারা ruct

এই প্রক্রিয়াগুলি ব্যবহারকারী-সংজ্ঞায়িত ক্লাসগুলিকে বিল্টিন ধরণের 'স্ট্যান্ডার্ড রূপান্তরগুলির অনুরূপ আচরণগুলি নির্দিষ্ট করার মঞ্জুরি দেয়। চল একটু দেখি:

int a, b;

if (std::cin >> a >> b)
    f(a, b);

এখানে, std::cinরূপান্তর অপারেটরের সাহায্যে অবজেক্টটি বুলিয়ান প্রসঙ্গে মূল্যায়ন করা হয়। উপরের বিষয়টিতে এটি স্ট্যান্ডার্ড রূপান্তরগুলি থেকে "ইন্টিগ্রাল প্রচার" এবং এটিকে ধারণাগতভাবে গোষ্ঠীভুক্ত করা যেতে পারে।

অন্তর্ভুক্ত নির্মাতারা কার্যকরভাবে একই কাজ করে তবে কাস্ট-টু টাইপ দ্বারা নিয়ন্ত্রিত হয়:

f(const std::string& x);
f("hello");  // invokes `std::string::string(const char*)`

সংকলন সরবরাহকৃত ওভারলোড, রূপান্তর এবং জবরদস্তির প্রভাব

বিবেচনা:

void f()
{
    typedef int Amount;
    Amount x = 13;
    x /= 2;
    std::cout << x * 1.1;
}

xবিভাগটি চলাকালীন আমরা যদি এই পরিমাণটি একটি আসল সংখ্যা হিসাবে বিবেচনা করতে চাই (অর্থাত্ 6 এর চেয়ে আরও 6.5 হওয়া উচিত) তবে আমাদের কেবল পরিবর্তিত হওয়া দরকার typedef double Amount

এটি দুর্দান্ত, তবে কোডটি স্পষ্টভাবে "সঠিকভাবে" টাইপ করা খুব বেশি কাজ হত না :

void f()                               void f()
{                                      {
    typedef int Amount;                    typedef double Amount;
    Amount x = 13;                         Amount x = 13.0;
    x /= 2;                                x /= 2.0;
    std::cout << double(x) * 1.1;          std::cout << x * 1.1;
}                                      }

তবে, বিবেচনা করুন যে আমরা প্রথম সংস্করণটিকে একটি রূপান্তর করতে পারি template:

template <typename Amount>
void f()
{
    Amount x = 13;
    x /= 2;
    std::cout << x * 1.1;
}

এটি সেই "ছোট্ট সুবিধামত বৈশিষ্ট্যগুলি" এর কারণে এটি এত সহজেই হয় তত সহজেই ইনস্ট্যান্ট করা যায় intবা হয় doubleএবং যেমনটি কাজ করে তেমন কাজ করে। এই বৈশিষ্ট্যগুলি ব্যতীত আমাদের সুস্পষ্ট ক্যাসট, বৈশিষ্ট্য এবং / অথবা নীতি ক্লাস, কিছু শব্দাবলীর, ত্রুটি-ঝুঁকিপূর্ণ জগাখিচুড়ি যেমন দরকার:

template <typename Amount, typename Policy>
void f()
{
    Amount x = Policy::thirteen;
    x /= static_cast<Amount>(2);
    std::cout << traits<Amount>::to_double(x) * 1.1;
}

সুতরাং, বিল্টিন ধরণের, স্ট্যান্ডার্ড রূপান্তরগুলি, ingালাই / জবরদস্তি / অন্তর্নিহিত কন্সট্রাক্টরগুলির জন্য সংকলক-সরবরাহকারী অপারেটর ওভারলোডিং - তারা সবাই পলিমারফিজমের জন্য সূক্ষ্ম সমর্থন অবদান রাখে। এই উত্তরের উপরের সংজ্ঞা থেকে তারা ম্যাপিংয়ের মাধ্যমে "টাইপ-উপযুক্ত কোডটি সন্ধান এবং সম্পাদন করে" সম্বোধন করে:

  • প্যারামিটার ধরণের থেকে "দূরে"

    • পলিমর্ফিক অ্যালগরিদমিক কোড হ্যান্ডলগুলি থেকে প্রচুর ডেটা ধরণের

    • থেকে একটি (সম্ভাব্য ক্ষুদ্রতর) (একই বা অন্যান্য) প্রকারের সংখ্যার জন্য লেখা কোড।

  • ধ্রুবক ধরণের মান থেকে প্যারামেট্রিক ধরণের "থেকে"

তারা না নিজেরাই বহুরুপী প্রেক্ষিতে স্থাপন, কিন্তু এই ধরনের প্রেক্ষিতে ভিতরে সাহায্যের ক্ষমতায়ন / প্রক্রিয়া সহজ কোড না।

আপনি প্রতারিত বোধ করতে পারেন ... এটি অনেকটা মনে হয় না। তাত্পর্যটি হ'ল প্যারাম্যাট্রিক পলিমর্ফিক প্রসঙ্গে (অর্থাত্ টেমপ্লেট বা ম্যাক্রোগুলির অভ্যন্তরে) আমরা একটি নির্বিচারে বড় ধরণের প্রকারকে সমর্থন করার চেষ্টা করছি তবে প্রায়শই অন্যান্য ক্রিয়াকলাপ, আক্ষরিক এবং ক্রিয়াকলাপগুলির জন্য তাদের উপর ক্রিয়াকলাপ প্রকাশ করতে চাই যা একটি ডিজাইন করা হয়েছিল প্রকারের ছোট সেট। অপারেশন / মান যৌক্তিকভাবে একই হয়ে গেলে এটি প্রতি-টাইপ ভিত্তিতে কাছাকাছি-অভিন্ন ফাংশন বা ডেটা তৈরির প্রয়োজনীয়তা হ্রাস করে। এই বৈশিষ্ট্যগুলি "সেরা চেষ্টা" এর মনোভাব যুক্ত করতে সহযোগিতা করে, সীমিত উপলব্ধ ফাংশন এবং ডেটা ব্যবহার করে স্বজ্ঞাতভাবে যা প্রত্যাশা করা হয় তা করে এবং যখন সত্যিকারের অস্পষ্টতা থাকে কেবল তখনই একটি ত্রুটি থামিয়ে দেয়।

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


1
-1 পরিভাষা আলোচনা বাদে দুর্দান্ত উত্তর। সি ++ স্ট্যান্ডার্ড pol1.8 / 1-তে "পলিমারফিক" শব্দটি সংজ্ঞায়িত করে, সেখানে ভার্চুয়াল ফাংশনগুলি সম্পর্কে 10.3 অনুচ্ছেদ উল্লেখ করা হয়েছে। সুতরাং কোনও উইগল-রুম নেই, আলোচনার জন্য কোনও ঘর নেই, ব্যক্তিগত মতামতের কোনও স্থান নেই: স্ট্যান্ডার্ড সি ++ এর প্রসঙ্গে সেই শব্দটি একবারে এবং সকলের জন্য সংজ্ঞায়িত করা হয়। এবং এটি একটি অনুশীলন রোল খেলে। উদাহরণস্বরূপ, প্রায় §5.2.7 / 6 এর dynamic_castজন্য "পলিমারফিক ধরণের পয়েন্টার বা একটি লভ্যালু" প্রয়োজন। চিয়ার্স এবং এইচটি।,
চিয়ার্স এবং এইচটিএইচ। - আলফ

@ অ্যালফ: দুর্দান্ত রেফারেন্স - যদিও আমি মনে করি আপনার দৃষ্টিভঙ্গি খুব সংকীর্ণ। প্রশ্ন তালিকা ওভারলোডিং, অ্যাড-হক এবং প্যারামেট্রিক পলিমারফিজম ইত্যাদি থেকে এটি খুব স্পষ্ট যে উত্তরটি সাধারণ কম্পিউটারের সাথে সি ++ এর ক্ষমতা সম্পর্কিত থাকতে পারে। সী। পদগুলির অর্থ প্রকৃতপক্ষে, স্ট্রোস্ট্রপের গ্লসারিটি বলেছে "পলিমর্ফিজম - বিভিন্ন ধরণের সত্তাকে একক ইন্টারফেস সরবরাহ করে। ভার্চুয়াল ফাংশনগুলি একটি বেস শ্রেণীর সরবরাহিত একটি ইন্টারফেসের মাধ্যমে গতিশীল (রান-টাইম) পলিমারফিজম সরবরাহ করে Over টিসি ++ পিএল 12.2.6, 13.6.1, ডি ও ই 2.9। "
টনি দেলরোয়

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

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

1
@ অ্যালফ: দ্বিতীয়ত, আমি দৃ confident়বিশ্বাসের যে যে কোনও শালীন জেনারেল কম্পে পলিমারফিজমটি আনুষ্ঠানিকভাবে সংজ্ঞায়িত হয়েছে। সী। আমার ব্যবহারের সাথে সামঞ্জস্যপূর্ণ (কালজয়ী, স্থিতিশীল) উপায়ে বই (এবং স্ট্রস্ট্রুপ) উইকিপিডিয়া নিবন্ধটি কয়েকটি একাডেমিক প্রকাশনাগুলির সাথে এটি সংজ্ঞায়িত করেছে: "পলিমর্ফিক ফাংশনগুলি এমন ফাংশন যাগুলির অপারেশনগুলি (প্রকৃত পরামিতি) একাধিক প্রকারের হতে পারে Pol পলিমারফিক প্রকারগুলি এমন এক ধরণের যাগুলির ক্রিয়াকলাপগুলি একাধিক প্রকারের মানগুলির জন্য প্রযোজ্য" " ( লুকাকার্ডেলি.নেম / পেপারস / অনার্সেন্ডিং.এ ৪.পিডিএফ থেকে )। সুতরাং, প্রশ্নটি হল "কমপ্যাক্ট সায়েন্সের পক্ষে কে কথা বলেন" ...?
টনি ডেলরয়

15

সি ++ এ, গুরুত্বপূর্ণ পার্থক্যটি রান-টাইম বনাম কমপাইল-টাইম বাইন্ডিং। অ্যাড-হক বনাম প্যারামেট্রিক সত্যিই সহায়তা করে না, কারণ আমি পরে ব্যাখ্যা করব।

|----------------------+--------------|
| Form                 | Resolved at  |
|----------------------+--------------|
| function overloading | compile-time |
| operator overloading | compile-time |
| templates            | compile-time |
| virtual methods      | run-time     |
|----------------------+--------------|

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

ফাংশন ওভারলোডিং এবং অপারেটর ওভারলোডিং যে বিষয়টি গুরুত্বপূর্ণ সেভাবেই একই জিনিস। নামগুলি এবং তাদের ব্যবহারের বাক্য গঠনটি বহুবর্ষকে প্রভাবিত করে না।

টেমপ্লেটগুলি আপনাকে একবারে প্রচুর ফাংশন ওভারলোডগুলি নির্দিষ্ট করার অনুমতি দেয়।

একই রেজোলিউশন-সময় ধারণার জন্য আরও একটি নাম রয়েছে ...

|---------------+--------------|
| early binding | compile-time |
| late binding  | run-time     |
|---------------+--------------|

এই নামগুলি ওওপি-র সাথে বেশি যুক্ত, তাই কোনও টেমপ্লেট বা অন্যান্য সদস্যবিহীন ফাংশনটি প্রারম্ভিক বাঁধাই ব্যবহার করে তা বলাই বাহুল্য।

ভার্চুয়াল ফাংশন এবং ফাংশন ওভারলোডিংয়ের মধ্যে সম্পর্কটি আরও ভালভাবে বুঝতে, এটি "একক প্রেরণ" এবং "একাধিক প্রেরণ" এর মধ্যে পার্থক্যটি বোঝাও কার্যকর useful ধারণাটি অগ্রগতি হিসাবে বোঝা যায় ...

  • প্রথমত, মনোমরফিক ফাংশন রয়েছে। ফাংশনটির বাস্তবায়নটি ফাংশনের নাম দ্বারা স্বতন্ত্রভাবে চিহ্নিত করা হয়। প্যারামিটারগুলির কোনও বিশেষ নয়।
  • তারপরে, একক প্রেরণ আছে। কোনটি প্যারামিটারকে বিশেষ হিসাবে বিবেচনা করা হয় এবং কোনটি প্রয়োগ করতে হবে তা সনাক্ত করতে (নামের সাথে) ব্যবহৃত হয়। ওওপি-তে, আমরা এই প্যারামিটারটিকে "অবজেক্ট" হিসাবে ভাবি, ফাংশনের নামের আগে এটি তালিকাবদ্ধ করবো etc.
  • তারপরে, একাধিক প্রেরণ রয়েছে। কোনও / সমস্ত পরামিতি কোন প্রয়োগ ব্যবহার করতে হবে তা সনাক্ত করতে অবদান রাখে। অতএব, আবারও, প্যারামিটারগুলির কোনওটির বিশেষ হওয়া দরকার।

স্পষ্টতই ওওপি-র আরও একটি প্যারামিটারকে বিশেষ হিসাবে মনোনীত করার অজুহাত ছাড়াও রয়েছে, তবে এটি এরই একটি অংশ। এবং ট্রেড-অফ সম্পর্কে আমি যা বলেছিলাম তার সাথে সম্পর্কিত - একক প্রেরণ দক্ষতার সাথে করা বেশ সহজ (সাধারণ বাস্তবায়নটিকে "ভার্চুয়াল টেবিল" বলা হয়)। একাধিক প্রেরণ আরও দক্ষতার সাথে, কেবল দক্ষতার দিক থেকে নয়, পৃথক সংকলনের জন্যও। আপনি যদি কৌতূহলী হন তবে আপনি "অভিব্যক্তি সমস্যা" সন্ধান করতে পারেন।

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

প্যারামেট্রিক বনাম অ্যাড-হক পলিমॉर्फিজমে ফিরে আসা, এই পদগুলি কার্যকরী প্রোগ্রামিংয়ে বেশি জনপ্রিয় এবং এটি সি ++ তে বেশিরভাগ কাজ করে না। তারপরও...

প্যারামেট্রিক পলিমারফিজম বলতে বোঝায় যে আপনার পরামিতি হিসাবে প্রকার রয়েছে এবং সেই একই পরামিতিগুলির জন্য আপনি কোন ধরণের ব্যবহার করেন তা নির্বিশেষে সঠিক একই কোডটি ব্যবহৃত হয়।

অ্যাড-হক পলিমারফিজমটি এই অর্থে অ্যাড-হক যে আপনি নির্দিষ্ট ধরণের উপর নির্ভর করে বিভিন্ন কোড সরবরাহ করেন।

ওভারলোডিং এবং ভার্চুয়াল ফাংশন উভয়ই অ্যাড-হক পলিমারফিজমের উদাহরণ।

আবার কিছু প্রতিশব্দ আছে ...

|------------+---------------|
| parametric | unconstrained |
| ad-hoc     | constrained   |
|------------+---------------|

এগুলি পুরোপুরি প্রতিশব্দ নয়, যদিও এগুলি সাধারণত যেমন ছিল তেমন আচরণ করা হয় এবং সি ++ এ বিভ্রান্তি দেখা দেওয়ার সম্ভাবনা রয়েছে।

এগুলি প্রতিশব্দ হিসাবে বিবেচনা করার পিছনে যুক্তিটি হল যে বহুবর্ষকে নির্দিষ্ট শ্রেণীর ধরণের ক্ষেত্রে সীমাবদ্ধ করে সেই ধরণের শ্রেণির সাথে সম্পর্কিত অপারেশনগুলি ব্যবহার করা সম্ভব হয়। এখানে "শ্রেণি" শব্দের অর্থ ওওপি অর্থে ব্যাখ্যা করা যায়, তবে সত্যিকার অর্থে (সাধারণত নাম দেওয়া হয়) নির্দিষ্ট ক্রিয়াকলাপগুলি ভাগ করে এমন ধরণের সেটগুলি বোঝায়।

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

যেমন হাস্কেল, আপনি থাকতে পারেন ...

myfunc1 :: Bool -> a -> a -> a
myfunc1 c x y = if c then x else y

aএখানে একটি সংকোচহীন বহুরুপী প্রকার। এটি যে কোনও কিছু হতে পারে, তাই আমরা এই ধরণের মানগুলির সাথে অনেক কিছুই করতে পারি না।

myfunc2 :: Num a => a -> a
myfunc2 x = x + 3

এখানে, শ্রেণীর aসদস্য হতে বাধ্য Num- এমন সংখ্যার মতো কাজ করে এমন ধরণগুলি। এই সীমাবদ্ধতা আপনাকে সেই মানগুলি যুক্ত করতে যেমন সংখ্যা-ইশ জিনিসগুলি করার অনুমতি দেয় them এমনকি 3যে আপনি কি বলতে চান আউট টাইপ অনুমান পরিসংখ্যান - বহুরুপী হয় 3ধরনের a

আমি এটিকে সীমাবদ্ধ প্যারামেট্রিক পলিমারফিজম হিসাবে মনে করি। কেবলমাত্র একটি বাস্তবায়ন রয়েছে, তবে এটি কেবল বাধা ক্ষেত্রে প্রয়োগ করা যেতে পারে। অ্যাড-হক দিকটি হ'ল কোনটির পছন্দ +এবং 3ব্যবহার। প্রতিটি "উদাহরণ" Numএর নিজস্ব স্বতন্ত্র প্রয়োগ রয়েছে। এমনকি হাস্কেলতেও "প্যারামিমেট্রিক" এবং "নিরবচ্ছিন্ন" আসলে প্রতিশব্দ নয় - আমাকে দোষ দেবেন না, এটি আমার দোষ নয়!

সি ++ এ ওভারলোডিং এবং ভার্চুয়াল ফাংশন উভয়ই অ্যাড-হক পলিমারফিজম। অ্যাড-হক পলিমারফিজমের সংজ্ঞা প্রয়োগটি রান-টাইমে বা সংকলন-সময় নির্বাচিত কিনা তা বিবেচনা করে না।

প্রতিটি টেম্পলেট প্যারামিটারের টাইপ থাকলে সি ++ টেমপ্লেটগুলির সাথে প্যারামিমেট্রিক পলিমারফিজমের খুব কাছে চলে যায় typename। প্রকারের প্যারামিটার রয়েছে এবং কোন একক প্রয়োগ রয়েছে তা কোন ধরণের ব্যবহৃত হয় তা নয়। যাইহোক, "সাবস্টিটিউশন ব্যর্থতা একটি ত্রুটি নয়" নিয়মের অর্থ টেমপ্লেটের মধ্যে ক্রিয়াকলাপ ব্যবহারের ফলে অন্তর্নিহিত বাধা সৃষ্টি হয়। অতিরিক্ত জটিলতার মধ্যে বিকল্প টেমপ্লেটগুলি সরবরাহের জন্য টেমপ্লেট বিশেষায়িতকরণ - বিভিন্ন (অ্যাড-হক) বাস্তবায়ন রয়েছে।

সুতরাং একটি উপায়ে সি ++ এর প্যারামিটারিক পলিমারফিজম রয়েছে তবে এটি স্পষ্টতই বাধা হয়ে দাঁড়িয়েছে এবং অ্যাড-হক বিকল্পগুলির দ্বারা ওভাররাইড হয়ে যেতে পারে - অর্থাত এই শ্রেণিবিন্যাসটি সি ++ এর পক্ষে কার্যকরভাবে কাজ করে না।


+1 প্রচুর আকর্ষণীয় পয়েন্ট এবং অন্তর্দৃষ্টি। আমি হাস্কেল সম্পর্কে পড়তে কেবল কয়েক ঘন্টা ব্যয় করেছি তাই " aএখানে একটি অসংলগ্ন পলিমারফিক ধরণের [...] তাই আমরা এই ধরণের মানগুলির সাথে অনেক কিছুই করতে পারি না।" আগ্রহী ছিল - সি ++ সানস কনসেপ্টে আপনি কেবলমাত্র টেমপ্লেট প্যারামিটার হিসাবে নির্দিষ্ট টাইপের যুক্তিতে ক্রিয়াকলাপের নির্দিষ্ট সেট চেষ্টা করার মধ্যে সীমাবদ্ধ নন ... বুস্ট কনসেপ্টের মতো লাইব্রেরিগুলি অন্যভাবে কাজ করে - নিশ্চিত করে নিন যে টাইপটি অপারেশনগুলিকে সমর্থন করে আপনি অতিরিক্ত ক্রিয়াকলাপের দুর্ঘটনাজনিত ব্যবহার থেকে রক্ষা না করে নির্দিষ্ট করে দিন।
টনি ডেলরয়

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

"সামঞ্জস্যতার কারণে অন্তর্নিহিত বাধাগুলি অবশ্যই স্পষ্ট হবে না" - মেমরি থেকে, C ++ 0x ধারণাগুলি (প্রতিশ্রুতি দেয়: - /) "অন্তর্নিহিত বাধা" রোধ করে - আপনি কেবল ধারণাগুলির দ্বারা প্রতিশ্রুতি দেওয়া পদ্ধতিতে ব্যবহার করতে পারেন।
টনি দেলরোয়

2

অ্যাড-হক পলিমারফিজম হিসাবে এটির অর্থ ফাংশন ওভারলোডিং বা অপারেটর ওভারলোডিং। এখানে দেখুন:

http://en.wikipedia.org/wiki/Ad-hoc_polymorphism

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

http://en.wikipedia.org/wiki/Parametric_polymorphism


1
দুর্ভাগ্যক্রমে, যদিও সঠিক, এটি বিভ্রান্তিকর। টেমপ্লেট ফাংশনগুলি SFINAE নিয়মের কারণে অন্তর্নিহিত প্রতিবন্ধকতা পেতে পারে - টেম্পলেটটির মধ্যে একটি ক্রিয়াকলাপ স্পষ্টভাবে বহুবর্ষকে সীমাবদ্ধ করে - এবং টেমপ্লেট বিশেষায়িতকরণ আরও সাধারণ টেমপ্লেটগুলিকে ওভাররাইড করে এমন অ্যাড-হক বিকল্প টেম্পলেট সরবরাহ করতে পারে। সুতরাং একটি টেমপ্লেট (ডিফল্টরূপে) অনিয়ন্ত্রিত প্যারামিমেট্রিক পলিমারফিজম সরবরাহ করে, তবে এটির কোনও প্রয়োগ নেই - কমপক্ষে দুটি উপায় আছে যা এটি সীমাবদ্ধ বা অ্যাড-হক হতে পারে।
স্টিভ 314

আসলে আপনার উদাহরণ - বাছাই - একটি বাধা বোঝায়। বাছাই করা কেবলমাত্র সেই জাতীয় ধরণের জন্য কাজ করে (যেমন <এবং অনুরূপ অপারেটরগুলি সরবরাহ করে)। হাস্কেলে, আপনি প্রয়োজনীয়তাটি ক্লাসটি ব্যবহার করে স্পষ্টভাবে প্রকাশ করবেন Ord। আপনি <নির্দিষ্ট ধরণের উপর নির্ভর করে যে আলাদা হয়ে গেছেন (যেমন উদাহরণ হিসাবে সরবরাহ করা হয়েছে Ord) এটি অ্যাড-হক পলিমারফিজম হিসাবে বিবেচিত হবে।
স্টিভ 314

2

এটি কোনও উপকারে নাও আসতে পারে তবে আমি আমার বন্ধুদের প্রোগ্রামিংয়ের সাথে সংজ্ঞায়িত ফাংশনগুলি, পছন্দ মতো STARTএবং ENDমূল ফাংশনটি প্রদান করে পরিচয় করিয়ে দেওয়ার জন্য তৈরি করেছি যাতে এটি খুব বেশি উদ্বেগজনক হয় না (তারা কেবল মেইন সিপিপি ফাইল ব্যবহার করেছিল )। এটিতে পলিমারফিক ক্লাস এবং স্ট্রাক্টস, টেমপ্লেটস, ভেক্টর, অ্যারে, প্রিপ্রোকসেসর নির্দেশিকা, বন্ধুত্ব, অপারেটর এবং পয়েন্টার রয়েছে (যে সমস্ত কিছুই সম্ভবত পলিমারফিজম চেষ্টা করার আগে আপনার জানা উচিত) রয়েছে:

দ্রষ্টব্য: এটি সমাপ্ত নয়, তবে আপনি ধারণাটি পেতে পারেন

main.cpp

#include "main.h"
#define ON_ERROR_CLEAR_SCREEN false
START
    Library MyLibrary;
    Book MyBook("My Book", "Me");
    MyBook.Summarize();
    MyBook += "Hello World";
    MyBook += "HI";
    MyBook.EditAuthor("Joe");
    MyBook.EditName("Hello Book");
    MyBook.Summarize();
    FixedBookCollection<FairyTale> FBooks("Fairytale Books");
    FairyTale MyTale("Tale", "Joe");
    FBooks += MyTale;
    BookCollection E("E");
    MyLibrary += E;
    MyLibrary += FBooks;
    MyLibrary.Summarize();
    MyLibrary -= FBooks;
    MyLibrary.Summarize();
    FixedSizeBookCollection<5> Collection("My Fixed Size Collection");
    /* Extension Work */ Book* Duplicate = MyLibrary.DuplicateBook(&MyBook);
    /* Extension Work */ Duplicate->Summarize();
END

main.h

#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <type_traits>
#include <array>
#ifndef __cplusplus
#error Not C++
#endif
#define START int main(void)try{
#define END GET_ENTER_EXIT return(0);}catch(const std::exception& e){if(ON_ERROR_CLEAR_SCREEN){system("cls");}std::cerr << "Error: " << e.what() << std::endl; GET_ENTER_EXIT return (1);}
#define GET_ENTER_EXIT std::cout << "Press enter to exit" << std::endl; getchar();
class Book;
class Library;
typedef std::vector<const Book*> Books;
bool sContains(const std::string s, const char c){
    return (s.find(c) != std::string::npos);
}
bool approve(std::string s){
    return (!sContains(s, '#') && !sContains(s, '%') && !sContains(s, '~'));
}
template <class C> bool isBook(){
    return (typeid(C) == typeid(Book) || std::is_base_of<Book, C>());
}
template<class ClassToDuplicate> class DuplicatableClass{ 
public:
    ClassToDuplicate* Duplicate(ClassToDuplicate ToDuplicate){
        return new ClassToDuplicate(ToDuplicate);
    }
};
class Book : private DuplicatableClass<Book>{
friend class Library;
friend struct BookCollection;
public:
    Book(const char* Name, const char* Author) : name_(Name), author_(Author){}
    void operator+=(const char* Page){
        pages_.push_back(Page);
    }
    void EditAuthor(const char* AuthorName){
        if(approve(AuthorName)){
            author_ = AuthorName;
        }
        else{
            std::ostringstream errorMessage;
            errorMessage << "The author of the book " << name_ << " could not be changed as it was not approved";
            throw std::exception(errorMessage.str().c_str());
        }
    }
    void EditName(const char* Name){
        if(approve(Name)){
            name_ = Name;
        }
        else{
            std::ostringstream errorMessage;
            errorMessage << "The name of the book " << name_ << " could not be changed as it was not approved";
            throw std::exception(errorMessage.str().c_str());
        }
    }
    virtual void Summarize(){
        std::cout << "Book called " << name_ << "; written by " << author_ << ". Contains "
            << pages_.size() << ((pages_.size() == 1) ? " page:" : ((pages_.size() > 0) ? " pages:" : " pages")) << std::endl;
        if(pages_.size() > 0){
            ListPages(std::cout);
        }
    }
private:
    std::vector<const char*> pages_;
    const char* name_;
    const char* author_;
    void ListPages(std::ostream& output){
        for(int i = 0; i < pages_.size(); ++i){
            output << pages_[i] << std::endl;
        }
    }
};
class FairyTale : public Book{
public:
    FairyTale(const char* Name, const char* Author) : Book(Name, Author){}
};
struct BookCollection{
friend class Library;
    BookCollection(const char* Name) : name_(Name){}
    virtual void operator+=(const Book& Book)try{
        Collection.push_back(&Book); 
    }catch(const std::exception& e){
        std::ostringstream errorMessage;
        errorMessage << e.what() << " - on line (approx.) " << (__LINE__ -3);
        throw std::exception(errorMessage.str().c_str());
    }
    virtual void operator-=(const Book& Book){
        for(int i = 0; i < Collection.size(); ++i){
            if(Collection[i] == &Book){
                Collection.erase(Collection.begin() + i);
                return;
            }
        }
        std::ostringstream errorMessage;
        errorMessage << "The Book " << Book.name_ << " was not found, and therefore cannot be erased";
        throw std::exception(errorMessage.str().c_str());
    }
private:
    const char* name_;
    Books Collection;
};
template<class FixedType> struct FixedBookCollection : public BookCollection{
    FixedBookCollection(const char* Name) : BookCollection(Name){
        if(!isBook<FixedType>()){
            std::ostringstream errorMessage;
            errorMessage << "The type " << typeid(FixedType).name() << " cannot be initialized as a FixedBookCollection";
            throw std::exception(errorMessage.str().c_str());
            delete this;
        }
    }
    void operator+=(const FixedType& Book)try{
        Collection.push_back(&Book); 
    }catch(const std::exception& e){
        std::ostringstream errorMessage;
        errorMessage << e.what() << " - on line (approx.) " << (__LINE__ -3);
        throw std::exception(errorMessage.str().c_str());
    }
    void operator-=(const FixedType& Book){
        for(int i = 0; i < Collection.size(); ++i){
            if(Collection[i] == &Book){
                Collection.erase(Collection.begin() + i);
                return;
            }
        }
        std::ostringstream errorMessage;
        errorMessage << "The Book " << Book.name_ << " was not found, and therefore cannot be erased";
        throw std::exception(errorMessage.str().c_str());
    }
private:
    std::vector<const FixedType*> Collection;
};
template<size_t Size> struct FixedSizeBookCollection : private std::array<const Book*, Size>{
    FixedSizeBookCollection(const char* Name) : name_(Name){ if(Size < 1){ throw std::exception("A fixed size book collection cannot be smaller than 1"); currentPos = 0; } }
    void operator+=(const Book& Book)try{
        if(currentPos + 1 > Size){
            std::ostringstream errorMessage;
            errorMessage << "The FixedSizeBookCollection " << name_ << "'s size capacity has been overfilled";
            throw std::exception(errorMessage.str().c_str());
        }
        this->at(currentPos++) = &Book;
    }catch(const std::exception& e){
        std::ostringstream errorMessage;
        errorMessage << e.what() << " - on line (approx.) " << (__LINE__ -3);
        throw std::exception(errorMessage.str().c_str());
    }
private:
    const char* name_;
    int currentPos;
};
class Library : private std::vector<const BookCollection*>{
public:
    void operator+=(const BookCollection& Collection){
        for(int i = 0; i < size(); ++i){
            if((*this)[i] == &Collection){
                std::ostringstream errorMessage;
                errorMessage << "The BookCollection " << Collection.name_ << " was already in the library, and therefore cannot be added";
                throw std::exception(errorMessage.str().c_str());
            }
        }
        push_back(&Collection);
    }
    void operator-=(const BookCollection& Collection){
        for(int i = 0; i < size(); ++i){
            if((*this)[i] == &Collection){
                erase(begin() + i);
                return;
            }
        }
        std::ostringstream errorMessage;
        errorMessage << "The BookCollection " << Collection.name_ << " was not found, and therefore cannot be erased";
        throw std::exception(errorMessage.str().c_str());
    }
    Book* DuplicateBook(Book* Book)const{
        return (Book->Duplicate(*Book));
    }
    void Summarize(){
        std::cout << "Library, containing " << size() << ((size() == 1) ? " book collection:" : ((size() > 0) ? " book collections:" : " book collections")) << std::endl;
        if(size() > 0){
            for(int i = 0; i < size(); ++i){
                std::cout << (*this)[i]->name_ << std::endl;
            }
        }
    }
};

1

পলিমারফিক ক্লাস ব্যবহার করে এখানে একটি বুনিয়াদী উদাহরণ

#include <iostream>

class Animal{
public:
   Animal(const char* Name) : name_(Name){/* Add any method you would like to perform here*/
    virtual void Speak(){
        std::cout << "I am an animal called " << name_ << std::endl;
    }
    const char* name_;
};

class Dog : public Animal{
public:
    Dog(const char* Name) : Animal(Name) {/*...*/}
    void Speak(){
        std::cout << "I am a dog called " << name_ << std::endl;
    }
};

int main(void){
    Animal Bob("Bob");
    Dog Steve("Steve");
    Bob.Speak();
    Steve.Speak();
    //return (0);
}

0

পলিমারফিজম বলতে বোঝায় অনেকগুলি রূপ যেমন এটি কোনও অপারেটরকে বিভিন্ন পরিস্থিতিতে বিভিন্নভাবে আচরণ করতে ব্যবহৃত হয়। পলিমারফিজম উত্তরাধিকার প্রয়োগের জন্য ব্যবহৃত হয়। প্রাক্তন হিসাবে, আমরা একটি শ্রেণি আকারের জন্য একটি fn অঙ্কন () সংজ্ঞায়িত করেছি তারপরে অঙ্কন fn অঙ্কন বৃত্ত, বাক্স, ত্রিভুজ এবং অন্যান্য আকারের জন্য প্রয়োগ করা যেতে পারে। (যা শ্রেণি আকৃতির বস্তু)


-3

যদি কেউ এই লোকদের CUT বলে

The Surgeon
The Hair Stylist
The Actor

কি হবে?

The Surgeon would begin to make an incision.
The Hair Stylist would begin to cut someone's hair.
The Actor would abruptly stop acting out of the current scene, awaiting directorial guidance.

সুতরাং উপরোক্ত উপস্থাপনাটি ওওপিতে বহুমুখিতা (একই নাম, ভিন্ন আচরণ) কী তা দেখায়।

আপনি যদি কোনও সাক্ষাত্কারের জন্য যাচ্ছেন এবং সাক্ষাত্কারকারীর কাছে আমরা যে ঘরে বসে আছি সেই একই কক্ষে পলিমারফিজমের জন্য একটি জীবন্ত উদাহরণ বলতে / বলার জন্য বলে,

উত্তর - ডোর / উইন্ডোজ

ভাবছি কিভাবে?

ডোর / উইন্ডোর মাধ্যমে - কোনও ব্যক্তি আসতে পারে, বাতাস আসতে পারে, আলো আসতে পারে, বৃষ্টি আসতে পারে ইত্যাদি etc.

অর্থাত্ একরকম বিভিন্ন আচরণ (বহুবিজ্ঞান) গঠন করে।

এটি আরও ভাল এবং সহজ পদ্ধতিতে বোঝার জন্য আমি উপরের উদাহরণটি ব্যবহার করেছি .. আপনার যদি কোডের জন্য রেফারেন্সের প্রয়োজন হয় তবে উপরের উত্তরগুলি অনুসরণ করুন।


আমি সি ++ তে পলিমারফিজমটি আরও ভালভাবে বোঝার জন্য উল্লেখ করেছি যেমন আমি উপরের উদাহরণটি ব্যবহার করেছি। এটি কোনও ফ্রেশারকে সাক্ষাত্কারে অনুষ্ঠানের সময় কোডটির পিছনে আসলে কী অর্থ বা কী ঘটছে তা বুঝতে এবং তা বোঝাতে সহায়তা করতে পারে। ধন্যবাদ!
সঞ্চিত

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