নির্মাতারা কেন উত্তরাধিকারসূত্রে প্রাপ্ত হয় না?


33

কোনও কনস্ট্রাক্টর যদি বেস ক্লাস থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয় তবে সমস্যাগুলি কী হতে পারে তা নিয়ে আমি বিভ্রান্ত am সিপিপি প্রিমার প্লাস বলেছেন,

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

আমি বুঝতে পারি অবজেক্ট কনস্ট্রাকশন শেষ হওয়ার আগে কনস্ট্রাক্টরকে ডাকা হয়।

যদি কোনও শিশু শ্রেণি উত্তরাধিকার সূত্রে প্রাপ্ত হয় ( উত্তরাধিকার সূত্রে আমি বলতে চাইছি যে শিশু শ্রেণি পিতামাতার শ্রেণি পদ্ধতিটি ওভাররাইড করতে সক্ষম হয় তবে পিতা বা মাতা নির্বাহক কেবল পিতামাত্ত শ্রেণীর পদ্ধতিতে অ্যাক্সেস না করে )?

আমি বুঝতে পারি যে কোনও কোডের মধ্যে থেকে পরিষ্কারভাবে কোনও কনস্ট্রাক্টরকে কল করার প্রয়োজন নেই [অবজেক্ট তৈরি করার সময় বাদে আমি এখনও অবগত নই।] তারপরেও আপনি প্যারেন্ট কন্ডাক্টরকে আহ্বান করতে কিছু ব্যবস্থা ব্যবহার করে এটি করতে পারেন [সিপিতে, ব্যবহার ::বা ব্যবহার করে member initialiser list, জাভা ব্যবহার করে super]। জাভাতে এটি 1 ম লাইনে কল করার জন্য একটি প্রয়োগকারী রয়েছে, আমি বুঝতে পেরেছি যে প্যারেন্ট অবজেক্টটি প্রথমে তৈরি করা হয়েছে এবং তারপরে শিশু অবজেক্ট নির্মাণ এগিয়ে চলেছে তা নিশ্চিত করা।

এটি এটিকে ওভাররাইড করতে পারে। তবে, আমি এমন পরিস্থিতি নিয়ে আসতে পারি না যেখানে এটি কোনও সমস্যা তৈরি করতে পারে। যদি সন্তানের পিতা-মাতা নির্বাহকের উত্তরাধিকার হয় তবে কী ভুল হতে পারে?

তাই এটি কেবল অসম্পূর্ণ ফাংশনগুলির উত্তরাধিকার থেকে দূরে রাখা keep নাকি এর আরও কিছু আছে?


সি ++ 11 দিয়ে আসলেই গতি বাড়েনি, তবে আমি মনে করি এটিতে নির্মাণকারীর উত্তরাধিকারের কোনও ফর্ম রয়েছে।
ইয়ানিস

3
মনে রাখবেন আপনি কন্সট্রাক্টরগুলিতে যা কিছু করুন না কেন আপনাকে ধ্বংসকারীদের যত্ন নিতে হবে care
মনোজ আর

2
আমি মনে করি আপনাকে "কনস্ট্রাক্টরের উত্তরাধিকার সূত্রে প্রাপ্ত" বলতে কী বোঝাতে হবে তা নির্ধারণ করা দরকার। সমস্ত উত্তরের "কন্সট্রাক্টরকে উত্তরাধিকার সূত্রে প্রাপ্তি" অর্থ কী বলে তারতম্য বলে মনে হচ্ছে। আমি মনে করি না যে এগুলির কোনওটি আমার প্রাথমিক ব্যাখ্যাটির সাথে মেলে। উপরের "ধূসর বাক্সে" বর্ণনায় "উত্তরাধিকার হ'ল অর্থ একটি উত্পন্ন বস্তু একটি বেস-শ্রেণীর পদ্ধতি ব্যবহার করতে পারে" বোঝায় যে নির্মাণকারীরা উত্তরাধিকার সূত্রে প্রাপ্ত। একটি উত্পন্ন বস্তু অবশ্যই অবশ্যই বেস-শ্রেণীর কনস্ট্রাক্টর পদ্ধতিগুলি সর্বদা ব্যবহার করতে পারে এবং করতে পারে।
ডঙ্ক

1
কোনও নির্মাণকারীর উত্তরাধিকার সূত্রে স্পষ্টতার জন্য ধন্যবাদ, এখন আপনি কিছু উত্তর পেতে পারেন।
ডঙ্ক

উত্তর:


41

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

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

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

এই বৈশিষ্ট্যটি এইভাবে কাজ করে:

struct Base {
    Base(int a) : i(a) {}
    int i;
};

struct Derived : Base {
    Derived(int a, std::string s) : Base(a), m(s) {}

    using Base::Base; // Inherit Base's constructors.
    // Equivalent to:
    //Derived(int a) : Base(a), m() {}

    std::string m;
};

Derivedএখন দুটি কনস্ট্রাক্টর রয়েছে (অনুলিপি / মুভ কনস্ট্রাক্টর গণনা করছে না)। একটি যা একটি int এবং একটি স্ট্রিং নেয় এবং একটি যা কেবল কোনও int নেয়।


সুতরাং এটি ধরে নেওয়া হচ্ছে, শিশু শ্রেণীর নিজস্ব নির্মাতা থাকবে না? এবং উত্তরাধিকার সূত্রে প্রাপ্ত নির্মাণকর্তা স্পষ্টতই অজানা সন্তানের সদস্যদের এবং করণীয় সূচনা সম্পর্কে জানেন
সুবর্ণা পাতায়িল

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

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

1
m()কোথা থেকে এসেছে তা নির্দেশ করে বিবেচনা করুন এবং উদাহরণস্বরূপ যদি এর প্রকারটি হয় তবে এটি কীভাবে পরিবর্তিত হবে int
হস্তান্তরকারী 17

using Base::Baseজড়িতভাবে করা কি সম্ভব ? যদি আমি কোনও উদ্ভূত শ্রেণীর উপরের লাইনটি ভুলে গিয়েছি এবং সমস্ত উত্পন্ন ক্লাসে আমাকে কন্সট্রাক্টরের উত্তরাধিকারী করা দরকার - এটির পরে বড় মারাত্মক পরিণতি ঘটতে পারে
পোস্ট সেল্ফ

7

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

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

struct Base {
  virtual Base(unsigned p1, unsigned p2) {...}
};

struct Derived: public Base {
  Derived(unsigned p1, unsigned p2) : Base(p1, p2) override {...}
};

int main(void) {
  unsigned p1 = 0;
  unsigned p2 = 42;
  Derived *p_d1 = new Base(p1, p2); // This might call Derived(unsigned, unsigned).
  Derived *p_d2 = nullptr;
  p_d2 = new Base(p1, p2); // This might call Derived(unsigned, unsigned) too.
}

এক্ষেত্রে যে কনস্ট্রাক্টর নামক কনস্ট্রাক্টর নির্ধারিত তা ভেরিয়েবলের কনক্রিটের ধরণের উপর নির্ভর করে। পার্সিং / কোড উত্পন্ন করার সময় এটি সনাক্ত করা জটিল এবং এর কোনও ইউটিলিটি নেই: আপনি যে কংক্রিটটি তৈরি করছেন তা আপনি জানেন এবং উত্পন্ন শ্রেণীর জন্য আপনি একটি নির্দিষ্ট কনস্ট্রাক্টর লিখেছেন। নিম্নলিখিত বৈধ সি ++ কোডটি ঠিক একই কাজ করে, কিছুটা খাটো এবং এটি যা করে তাতে আরও স্পষ্ট:

struct Base {
  Base(unsigned p1, unsigned p2) {...}
};

struct Derived: public Base {
  Derived(unsigned p1, unsigned p2) : Base(p1, p2) {...}
};

int main(void) {
  unsigned p1 = 0;
  unsigned p2 = 42;
  Derived *p_d1 = new Derived(p1, p2); 
  Derived *p_d2 = nullptr;
  p_d2 = new Derived(p1, p2);
}


দ্বিতীয় ব্যাখ্যা বা সম্ভবত অতিরিক্ত প্রশ্ন হ'ল - বেস ক্লাসের নির্মাতারা যদি স্পষ্টভাবে গোপন না করা হয় তবে সমস্ত উত্পন্ন শ্রেণিতে স্বয়ংক্রিয়ভাবে উপস্থিত হত।

যদি সন্তানের পিতা-মাতা নির্বাহকের উত্তরাধিকার হয় তবে কী ভুল হতে পারে?

অভিভাবক কনস্ট্রাক্টরকে আড়াল করার জন্য আপনাকে অতিরিক্ত কোড লিখতে হবে যা উত্পন্ন শ্রেণীর গঠনে ব্যবহারের ক্ষেত্রে ভুল। এটি ঘটতে পারে যখন উত্পন্ন শ্রেণিটি বেস শ্রেণিকে এমনভাবে বিশেষজ্ঞ করে যাতে নির্দিষ্ট প্যারামিটারগুলি অপ্রাসঙ্গিক হয়ে যায়।

এর আদর্শ উদাহরণটি আয়তক্ষেত্র এবং স্কোয়ার (নোট করুন যে বর্গক্ষেত্র এবং আয়তক্ষেত্রগুলি সাধারণত লিসকোভ-সাবস্টিটিউটেবল হয় না তাই এটি খুব ভাল নকশা নয়, তবে এটি বিষয়টি হাইলাইট করে)।

struct Rectangle {
  Rectangle(unsigned width, unsigned height) {...}
};

struct Square : public Rectangle {
  explicit Square(unsigned side) : Rectangle(side, side) {...}
};

স্কয়ারটি যদি আয়তক্ষেত্রের দ্বি-মূল্য নির্মাতার উত্তরাধিকার সূত্রে প্রাপ্ত হয়, তবে আপনি আলাদা উচ্চতা এবং প্রস্থ সহ স্কোয়ারগুলি তৈরি করতে পারেন ... এটি যৌক্তিকভাবে ভুল, সুতরাং আপনি সেই নির্মাণকারীকে আড়াল করতে চাইবেন।


3

কনস্ট্রাক্টররা কেন উত্তরাধিকার সূত্রে প্রাপ্ত হয় না: উত্তরটি আশ্চর্যজনকভাবে সহজ: বেস শ্রেণীর নির্মাতা বেস বর্গটি তৈরি করে এবং উত্তরাধিকারী বর্গের নির্মাণকারী উত্তরাধিকারী বর্গকে "বিল্ড" করে " উত্তরাধিকার সূত্রে প্রাপ্ত শ্রেণি যদি নির্মাতার উত্তরাধিকারী হয় তবে কনস্ট্রাক্টর টাইপ বেস শ্রেণীর একটি অবজেক্ট তৈরি করার চেষ্টা করবে এবং আপনি উত্তরাধিকার সূত্রে প্রাপ্ত শ্রেণীর একটি বিষয় "বিল্ড" করতে সক্ষম হবেন না।

কোন শ্রেণীর অন্তর্নিহিত করার উদ্দেশ্যটি হ'ল ea


3

ভিত্তি শ্রেণীর নির্মাতাকে ওভাররাইড করার জন্য উদ্ভূত শ্রেণীর অনুমতি দেওয়ার ক্ষেত্রে সর্বাধিক সুস্পষ্ট সমস্যা হ'ল উদ্ভূত শ্রেণীর বিকাশকারী এখন তার বেস শ্রেণি (এস) কীভাবে তৈরি করবেন তা জানার জন্য দায়বদ্ধ। যখন ডাইরিভড ক্লাসটি বেস ক্লাসটি সঠিকভাবে তৈরি না করে তখন কী ঘটে?

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

উত্তরাধিকারের 1 স্তরেরও বেশি যুক্ত করা হলে এটি আরও জটিল is এখন আপনার উদ্ভূত শ্রেণীর কীভাবে সমস্ত বেস ক্লাসগুলি চেইন পর্যন্ত তৈরি করতে হবে তা জানতে হবে।

তারপরে যদি আপনি উত্তরাধিকারক্রমক্রমের শীর্ষে একটি নতুন বেস শ্রেণি যুক্ত করেন তবে কী ঘটে? আপনাকে উদ্ভূত শ্রেণি নির্মাতাদের সমস্ত আপডেট করতে হবে।


2

নির্মাতারা অন্যান্য পদ্ধতি থেকে মৌলিকভাবে পৃথক:

  1. আপনি তাদের না লিখলে এগুলি উত্পন্ন হয়।
  2. সমস্ত বেস শ্রেণি নির্মাতাকে আপনি ম্যানুয়ালি না করলেও অন্তর্নিহিত বলা হয়
  3. আপনি তাদের স্পষ্টভাবে কল করবেন না তবে বস্তু তৈরি করে।

তাহলে কেন তাদের উত্তরাধিকারসূত্রে পাওয়া যায় না? সহজ উত্তর: কারণ সর্বদা একটি ওভাররাইড থাকে, হয় হয় উত্পাদিত বা ম্যানুয়ালি লেখা written

কেন প্রতিটি শ্রেণীর একজন কনস্ট্রাক্টর দরকার? এটি একটি জটিল প্রশ্ন এবং আমি বিশ্বাস করি উত্তরটি সংকলক নির্ভর। "তুচ্ছ" কনস্ট্রাক্টরের মতো জিনিস রয়েছে যার জন্য সংকলক আদেশ দেয় না যে এটি বলা হবে বলে মনে হয়। আমি মনে করি যে উত্তরাধিকার হিসাবে আপনি যা বোঝায় তার নিকটতম জিনিস তবে উপরে বর্ণিত তিনটি কারণে আমি মনে করি নির্মাণকারীদের সাধারণ পদ্ধতির সাথে তুলনা করা আসলেই কার্যকর নয়। :)


1

প্রত্যেক শ্রেণীর জন্য একজন কনস্ট্রাক্টর এমনকি ডিফল্টদেরও প্রয়োজন।
সি ++ আপনার জন্য ডিফল্ট কনস্ট্রাক্টর তৈরি করবে যদি আপনি কোনও বিশেষ নির্মাতা তৈরি করেন তবে create
যদি আপনার বেস ক্লাসটি একটি বিশেষায়িত কন্সট্রাক্টর ব্যবহার করে, আপনার উভয়টি একই এবং এমনকি তাদের পিছনে শৃঙ্খলাবদ্ধ হলেও উত্পন্ন শ্রেণীর উপর আপনাকে বিশেষজ্ঞ কন্সট্রাক্টর লিখতে হবে।
সি ++ 11 আপনাকে ব্যবহার করে নির্মাণকারীর কোড নকল এড়াতে অনুমতি দেয় :

Class A : public B {
using B:B;
....
  1. উত্তরাধিকারী নির্মাণকারীদের একটি সেট গঠিত হয় of

    • বেস ক্লাসের সমস্ত অ-টেম্পলেট কনস্ট্রাক্টর (উপবৃত্তাকার প্যারামিটার বাদ দেওয়ার পরে, যদি থাকে) (সি ++ ১৪ থেকে)
    • ডিফল্ট আর্গুমেন্ট বা উপবৃত্তাকার প্যারামিটার সহ প্রতিটি কন্সট্রাক্টরের জন্য, উপবৃত্তটি ফেলে রেখে এবং আর্গুমেন্টের শেষ থেকে ডিফল্ট আর্গুমেন্ট বাদ দিয়ে তৈরি করা সমস্ত নির্মাণকারী স্বাক্ষর
    • বেস বর্গের সমস্ত কনস্ট্রাক্টর টেম্পলেট (উপবৃত্তাকার পরামিতি বাদ দেওয়ার পরে, যদি থাকে) (সি ++ ১৪ থেকে)
    • ডিফল্ট আর্গুমেন্ট বা উপবৃত্তিসহ প্রতিটি কনস্ট্রাক্টর টেমপ্লেটের জন্য, এলিপসিসটি ফেলে দিয়ে এবং আর্গুমেন্টের শেষ থেকে ডিফল্ট আর্গুমেন্ট বাদ দিয়ে তৈরি করা সমস্ত কনস্ট্রাক্টর সই
  2. সমস্ত উত্তরাধিকারী নির্মাতারা যারা ডিফল্ট নির্মাতা বা অনুলিপি / মুভ কনস্ট্রাক্টর নন এবং যার স্বাক্ষরগুলি উদ্ভূত শ্রেণিতে ব্যবহারকারী-সংজ্ঞায়িত কন্সট্রাক্টরের সাথে মেলে না, তারা স্পষ্টতই উদ্ভূত শ্রেণিতে ঘোষণা করা হয়েছে। ডিফল্ট পরামিতি উত্তরাধিকারসূত্রে প্রাপ্ত হয় না


0

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

MyClass() : Base()

আপনি জিজ্ঞাসা করছেন কেন এটি করতে হবে?

উপ-শ্রেণীর অতিরিক্ত বৈশিষ্ট্য থাকতে পারে যা নির্মাণকারীকে আরম্ভ করার প্রয়োজন হতে পারে, বা এটি বেস শ্রেণীর ভেরিয়েবলগুলি অন্যভাবে শুরু করতে পারে।

আপনি কীভাবে সাব-টাইপ অবজেক্টটি তৈরি করবেন?


ধন্যবাদ। প্রকৃতপক্ষে, আমি নির্ধারণের চেষ্টা করছি যে কেন অন্য নির্মাণকর্তা অন্যান্য অভিভাবক শ্রেণির পদ্ধতির মতো শিশু শ্রেণিতে উত্তরাধিকার সূত্রে প্রাপ্ত হয় না।
সুভর্ণা পাতায়িল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.