ডিজাইনের দৃষ্টিকোণ থেকে, কেন, সি ++ এ, কোনও বেস-ক্লাসের কোনও মা-নেই, সাধারণত object
অন্যান্য ভাষায় কী থাকে?
typedef
। আরও সাধারণ জেনেরিক শ্রেণিবিন্যাসের সাথে আপনি কেবল ব্যবহার করতে পারেন object
বা iterator
।
ডিজাইনের দৃষ্টিকোণ থেকে, কেন, সি ++ এ, কোনও বেস-ক্লাসের কোনও মা-নেই, সাধারণত object
অন্যান্য ভাষায় কী থাকে?
typedef
। আরও সাধারণ জেনেরিক শ্রেণিবিন্যাসের সাথে আপনি কেবল ব্যবহার করতে পারেন object
বা iterator
।
উত্তর:
স্ট্রোস্ট্রাপের এফএকিউগুলিতে সুনির্দিষ্ট রায় পাওয়া যায় । সংক্ষেপে, এটি কোনও অর্থপূর্ণ অর্থ বোঝায় না। এতে ব্যয় হবে। টেমপ্লেটগুলি ধারকগুলির জন্য আরও দরকারী।
কেন সি ++ এর সর্বজনীন শ্রেণীর অবজেক্ট নেই?
আমাদের একটির দরকার নেই: জেনেরিক প্রোগ্রামিং বেশিরভাগ ক্ষেত্রে স্ট্যাটিকালি টাইপ নিরাপদ বিকল্প সরবরাহ করে। অন্যান্য মামলা একাধিক উত্তরাধিকার ব্যবহার করে পরিচালনা করা হয়।
কোনও কার্যকর সার্বজনীন শ্রেণি নেই: সত্যিকারের সর্বজনীন তার নিজস্ব কোনও শব্দার্থ বহন করে না।
একটি "সার্বজনীন" শ্রেণি ধরণ এবং ইন্টারফেসগুলি সম্পর্কে opালু চিন্তাকে উত্সাহ দেয় এবং অতিরিক্ত রান-টাইম চেকিংয়ের দিকে পরিচালিত করে।
সর্বজনীন বেস শ্রেণি ব্যবহার করে ব্যয় বোঝায়: পলিমারফিক হওয়ার জন্য অবজেক্টগুলি গাদা-বরাদ্দ করতে হবে; এটি মেমরি এবং অ্যাক্সেস ব্যয়কে বোঝায়। গাদা বস্তু স্বাভাবিকভাবে অনুলিপি শব্দার্থবিজ্ঞান সমর্থন করে না। হিপ অবজেক্টস সহজ স্কোপড আচরণকে সমর্থন করে না (যা রিসোর্স ম্যানেজমেন্টকে জটিল করে তোলে)। একটি সর্বজনীন বেস শ্রেণিটি ডায়নামিক_কাস্ট এবং অন্যান্য রান-টাইম চেকিংয়ের ব্যবহারকে উত্সাহ দেয়।
Objects must be heap-allocated to be polymorphic
- আমি মনে করি না যে এই বিবৃতিটি সাধারণত সঠিক। আপনি অবশ্যই স্ট্যাকের উপর পলিমারফিক ক্লাসের উদাহরণ তৈরি করতে পারেন এবং এটির বেস ক্লাসগুলির মধ্যে একটিতে পয়েন্টার হিসাবে এটি পাঠাতে পারেন, বহুবর্ষচরিত আচরণের ফলন দেয়।
Foo
একটি রেফারেন্স-পারেন- মধ্যে Bar
যখন Bar
না উত্তরাধিকারী Foo
, deterministically একটি ব্যতিক্রম ছোঁড়ার। সি ++ তে, পয়েন্টার-টু-বারে পয়েন্টার-টু-ফু castালার চেষ্টা করার সময় সারা কনরকে মেরে ফেলার সময়টিতে একটি রোবট পাঠানো যেতে পারে।
আসুন প্রথমে আপনি কেন প্রথম স্থানে একটি বেস-শ্রেণি করতে চান তা নিয়ে ভাবুন think আমি কয়েকটি ভিন্ন কারণ সম্পর্কে ভাবতে পারি:
এই দুটি ভাল কারণ যে স্মলটালক, রুবি এবং অবজেক্টিভ-সি ব্র্যান্ডের ভাষার বেস-ক্লাস রয়েছে (প্রযুক্তিগতভাবে, অবজেক্টিভ সি-তে আসলে একটি বেস-ক্লাস নেই, তবে সমস্ত উদ্দেশ্য এবং উদ্দেশ্যে, এটি রয়েছে)।
# 1 এর জন্য, বেস-ক্লাসের প্রয়োজনীয়তা যা একক ইন্টারফেসের অধীনে সমস্ত বস্তুকে এক করে দেয় C ++ তে টেমপ্লেট অন্তর্ভুক্তি দ্বারা বিভক্ত হয়। এই ক্ষেত্রে:
void somethingGeneric(Base);
Derived object;
somethingGeneric(object);
অপ্রয়োজনীয়, যখন আপনি প্যারামেট্রিক পলিমারফিজমের মাধ্যমে সমস্ত ধরণের সততা বজায় রাখতে পারেন!
template <class T>
void somethingGeneric(T);
Derived object;
somethingGeneric(object);
# 2 এর জন্য, যদিও অবজেক্টিভ-সি তে, মেমরি পরিচালনার পদ্ধতিগুলি কোনও শ্রেণীর প্রয়োগের অংশ, এবং বেস বর্গ থেকে উত্তরাধিকার সূত্রে প্রাপ্ত হয়, সি ++ এ মেমরি পরিচালনা উত্তরাধিকারের পরিবর্তে রচনা ব্যবহার করে সঞ্চালিত হয়। উদাহরণস্বরূপ, আপনি একটি স্মার্ট পয়েন্টার মোড়ক সংজ্ঞায়িত করতে পারেন যা কোনও ধরণের বস্তুর উপর রেফারেন্স গণনা সম্পাদন করবে:
template <class T>
struct refcounted
{
refcounted(T* object) : _object(object), _count(0) {}
T* operator->() { return _object; }
operator T*() { return _object; }
void retain() { ++_count; }
void release()
{
if (--_count == 0) { delete _object; }
}
private:
T* _object;
int _count;
};
তারপরে, অবজেক্টটিতে নিজে কল করার পদ্ধতিগুলির পরিবর্তে, আপনি তার মোড়কে পদ্ধতিগুলি কল করবেন। এটি কেবল আরও জেনেরিক প্রোগ্রামিংকেই মঞ্জুরি দেয় না: এটি আপনাকে পৃথক উদ্বেগও করতে দেয় (যেহেতু আদর্শিকভাবে, আপনার অবজেক্টটি কী করা উচিত সে সম্পর্কে আরও উদ্বিগ্ন হওয়া উচিত, এর মেমরিটি বিভিন্ন পরিস্থিতিতে কীভাবে পরিচালনা করা উচিত)।
শেষ অবধি, যে ভাষাতে সি ++ এর মতো আদিম এবং প্রকৃত উভয় অবজেক্ট রয়েছে, সেখানে বেস-ক্লাস ( প্রতিটি মানের জন্য একটি ধারাবাহিক ইন্টারফেস ) থাকার সুবিধা হারাতে থাকে, তখন থেকে আপনার নির্দিষ্ট মান রয়েছে যা সেই ইন্টারফেসের সাথে সামঞ্জস্য করতে পারে না। এই ধরণের পরিস্থিতিতে আদিম ব্যবহার করার জন্য আপনাকে সেগুলিকে বস্তুতে তুলতে হবে (যদি আপনার সংকলক স্বয়ংক্রিয়ভাবে এটি না করে)। এটি অনেক জটিলতা সৃষ্টি করে।
সুতরাং, আপনার প্রশ্নের সংক্ষিপ্ত উত্তর: সি ++ এর বেস-ক্লাস নেই কারণ টেমপ্লেটগুলির মাধ্যমে প্যারামেট্রিক পলিমারফিজম থাকার দরকার নেই।
object
System.Object
int
System.Int32
std::shared_ptr
যা পরিবর্তে ব্যবহার করা উচিত।
সি ++ ভেরিয়েবলের প্রভাবশালী দৃষ্টান্তটি পাস-বাই-রেফ নয়, পাস-বাই-রেফ। সমস্ত কিছুকে রুট থেকে উত্সাহিত করতে বাধ্য করা Object
তাদেরকে একটি ত্রুটি আইপিএস ফ্যাক্টোর দ্বারা মূল্য দিয়ে যায়।
(কারণ কোনও বস্তুকে প্যারামিটার হিসাবে মান হিসাবে গ্রহণ করা, সংজ্ঞায়িতভাবে এটি কেটে ফেলা হবে এবং এর আত্মাকে সরিয়ে ফেলবে)।
এটি অপ্রয়োজনীয়। সি ++ আপনাকে মান প্রদান করে বা রেফারেন্স শব্দার্থবিজ্ঞান চাইছিল কিনা তা সম্পর্কে আপনাকে ভাবিয়ে তোলে, আপনাকে পছন্দ দেয়। পারফরম্যান্স কম্পিউটিংয়ে এটি একটি বড় বিষয়।
Object
হওয়া তুলনামূলকভাবে সামান্য হবে।
সমস্যাটি হ'ল সি ++ তে এই জাতীয় টাইপ রয়েছে! এটা হয় void
। :-) যে কোনও পয়েন্টারকে নিরাপদে অন্তর্নিহিতভাবে কাস্ট করা যেতে পারে void *
, এতে বেসিক টাইপের পয়েন্টার সহ, ভার্চুয়াল টেবিলবিহীন ক্লাস এবং ভার্চুয়াল টেবিল সহ ক্লাস রয়েছে।
যেহেতু এটি সমস্ত বিভাগের অবজেক্টের সাথে সামঞ্জস্যপূর্ণ হওয়া উচিত, তাই void
এতে ভার্চুয়াল পদ্ধতি থাকতে পারে না। ভার্চুয়াল ফাংশন এবং আরটিটিআই ব্যতীত, প্রকার সম্পর্কিত কোনও কার্যকর তথ্য পাওয়া যাবে না void
(এটি প্রতিটি ধরণের সাথে মেলে, তাই কেবল প্রতিটি জিনিসই সত্য যা কিছু বলতে পারে) তবে ভার্চুয়াল ফাংশন এবং আরটিটিআই সাধারণ প্রকারকে খুব অকার্যকর করে দেয় এবং সি ++ হওয়া থেকে বিরত রাখে সরাসরি স্মৃতি অ্যাক্সেস সহ নিম্ন-স্তরের প্রোগ্রামিংয়ের জন্য উপযুক্ত একটি ভাষা etc.
সুতরাং, এই ধরনের আছে। এটি ভাষার স্বল্প-স্তরের প্রকৃতির কারণে কেবল খুব সংক্ষিপ্ততর (আসলে খালি) ইন্টারফেস সরবরাহ করে। :-)
void
।
void
এটা কম্পাইল করবে না এবং আপনি পেতে এই ত্রুটি । জাভাতে আপনার টাইপের একটি পরিবর্তনশীল থাকতে পারে Object
এবং এটি কাজ করবে। এটি void
একটি "বাস্তব" টাইপের মধ্যে পার্থক্য । সম্ভবত এটি সত্য যে void
প্রতিটি কিছুর জন্য বেস টাইপ, তবে এটি কোনও নির্মাণকারী, পদ্ধতি বা ক্ষেত্র সরবরাহ করে না, এটি আছে কি নেই তা বলার উপায় নেই। এই দাবিটি প্রমাণ বা অস্বীকার করা যায় না।
void
এটি একটি প্রকার (এবং এর কিছুটা চালাক ব্যবহারের সন্ধান? :
পেয়েছিল) তবে এটি এখনও সর্বজনীন বেস শ্রেণি হতে অনেক দীর্ঘ পথ। একটি জিনিসের জন্য, এটি "একটি অসম্পূর্ণ প্রকার যা সম্পূর্ণ করা যায় না" এবং অন্যটির জন্য কোনও void&
প্রকার নেই।
সি ++ একটি দৃ strongly়ভাবে টাইপ করা ভাষা। তবুও এটি আশ্চর্যজনক যে টেমপ্লেট বিশেষায়নের প্রসঙ্গে এটিতে সর্বজনীন কোনও অবজেক্টের ধরণ নেই।
উদাহরণস্বরূপ, প্যাটার্নটি ধরুন
template <class T> class Hook;
template <class ReturnType, class ... ArgTypes>
class Hook<ReturnType (ArgTypes...)>
{
...
ReturnType operator () (ArgTypes... args) { ... }
};
যা তাত্ক্ষণিকভাবে করা যেতে পারে
Hook<decltype(some_function)> ...;
এখন ধরে নেওয়া যাক আমরা একটি নির্দিষ্ট ফাংশনের জন্য একই চাই। পছন্দ
template <auto fallback> class Hook;
template <auto fallback, class ReturnType, class ... ArgTypes>
class Hook<ReturnType fallback(ArgTypes...)>
{
...
ReturnType operator () (ArgTypes... args) { ... }
};
বিশেষায়িত তাত্পর্য সহ
Hook<some_function> ...
তবে হায়, যদিও ক্লাস টি বিশেষায়নের আগে যে কোনও ধরণের (শ্রেণি বা না) জন্য দাঁড়াতে পারে, এর কোনও সমতুল্য নেই auto fallback
(আমি এই সিনট্যাক্সটিকে এই প্রসঙ্গে সর্বাধিক সুস্পষ্ট জেনেরিক নন-টাইপ হিসাবে ব্যবহার করছি) যে কোনওটির পক্ষে দাঁড়াতে পারে বিশেষায়নের আগে নন-টাইপ টেম্পলেট যুক্তি।
সুতরাং সাধারণভাবে এই প্যাটার্নটি টাইপ টেম্পলেট আর্গুমেন্ট থেকে অ-টাইপ টেম্পলেট আর্গুমেন্টে স্থানান্তর করে না।
সি ++ ভাষায় প্রচুর কোণার মতো, উত্তরটি সম্ভবত "কোনও কমিটির সদস্যই এটি নিয়ে ভাবেননি"।
ReturnType fallback(ArgTypes...)
কাজ করে তবে এটি খারাপ নকশা হবে। template <class T, auto fallback> class Hook; template <class ReturnType, class ... ArgTypes> class Hook<ReturnType (ArgTypes...), ReturnType(*fallback)(ArgTypes...)> ...
আপনি যা চান তা করে এবং এর টেমপ্লেট প্যারামিটারগুলি Hook
ধারাবাহিক ধরণের হয়
সি ++ প্রথমে বলা হত "সি উইথ ক্লাস"। এটি সি ভাষার মতো আরও কিছু আধুনিক জিনিসের বিপরীতে সি ভাষার একটি অগ্রগতি। এবং আপনি ভাষা হিসাবে সি ++ দেখতে পাচ্ছেন না, তবে ভাষার ভিত্তি হিসাবে (হ্যাঁ, আমি স্কট মায়ার্স এর কার্যকরী সি ++ স্মরণ করছি)।
সি নিজেই ভাষার মিশ্রণ, সি প্রোগ্রামিং ভাষা এবং এর প্রিপ্রোসেসর or
সি ++ আরও একটি মিশ্রণ যুক্ত করে:
বর্গ / অবজেক্টের পদ্ধতির
টেম্পলেট
এসটিএল
আমি ব্যক্তিগতভাবে এমন কিছু জিনিস পছন্দ করি না যা সরাসরি সি থেকে সি ++ এ আসে। একটি উদাহরণ এনাম বৈশিষ্ট্য। সি # যেভাবে বিকাশকারীকে এটি ব্যবহারের অনুমতি দেয় তা আরও ভাল: এটি এনামকে তার নিজস্ব সুযোগে সীমাবদ্ধ করে দেয়, এর একটি কাউন্ট সম্পত্তি রয়েছে এবং এটি সহজেই পুনরাবৃত্তিযোগ্য।
যেহেতু সি ++ সি এর সাথে পুনঃপ্রবিযোগী হতে চেয়েছিল, তাই ডিজাইনার সি ভাষাটিকে পুরো সি ++ তে প্রবেশ করার অনুমতি দেওয়ার জন্য খুব অনুমতিপ্রাপ্ত ছিল (কিছু সূক্ষ্ম পার্থক্য রয়েছে, তবে আপনি কোনও সি সংকলক ব্যবহার করে যা করতে পেরেছিলেন তা আমি মনে করি না যে আপনি একটি সি ++ সংকলক ব্যবহার করে না করতে পারে)।