খালি বেস অপ্টিমাইজেশন দুর্দান্ত। তবে এটি নিম্নলিখিত বিধিনিষেধের সাথে আসে:
খালি বেস ক্লাসগুলির মধ্যে একটি যদি প্রথম অ স্থিতিশীল ডাটা সদস্যের প্রকারের ভিত্তি বা ভিত্তি হয় তবে খালি বেস অপ্টিমাইজেশন নিষিদ্ধ করা হয়, যেহেতু একই ধরণের দুটি বেস সাবোবজেক্টের অবজেক্টের উপস্থাপনের মধ্যে আলাদা ঠিকানা থাকতে হবে সর্বাধিক উদ্ভূত প্রকারের।
এই সীমাবদ্ধতার ব্যাখ্যা দিতে, নিম্নলিখিত কোডটি বিবেচনা করুন। static_assert
ব্যর্থ হবে। তবে, পরিবর্তিত হয়ে Foo
বা Bar
পরিবর্তে উত্তরাধিকার সূত্রে Base2
পরিবর্তন করলে ত্রুটিটি এড়ানো যাবে:
#include <cstddef>
struct Base {};
struct Base2 {};
struct Foo : Base {};
struct Bar : Base {
Foo foo;
};
static_assert(offsetof(Bar,foo)==0,"Error!");
আমি এই আচরণটি পুরোপুরি বুঝতে পারি। আমি যা বুঝতে পারি না তা হ'ল এই বিশেষ আচরণটি কেন বিদ্যমান । এটি স্পষ্টতই একটি কারণে যুক্ত করা হয়েছে, কারণ এটি একটি সুস্পষ্ট সংযোজন, তদারকি নয়। এর পক্ষে যুক্তি কী?
বিশেষত, দুটি বেস সাবোবজেক্টের আলাদা ঠিকানা থাকতে হবে কেন? উপরের দিকে, Bar
একটি প্রকার এবং foo
সেই ধরণের একটি সদস্য ভেরিয়েবল। আমি দেখতে পাচ্ছি না কেন বেসের বর্গটি Bar
ধরণের ধরণের foo
বা বিপরীত দিকের বেস শ্রেণীর সাথে সম্পর্কিত ।
প্রকৃতপক্ষে, আমি যদি কিছু বলি তবে আমি এটির &foo
সাথে থাকা Bar
উদাহরণের ঠিকানার মতোই আশা করব other যেমনটি অন্যান্য পরিস্থিতিতে হওয়া প্রয়োজন (1) । সর্বোপরি, আমি virtual
উত্তরাধিকার নিয়ে অভিনব কিছু করছি না , বেস ক্লাস নির্বিশেষে খালি, এবং সংকলন Base2
দেখায় যে এই বিশেষ ক্ষেত্রে কিছুই ভাঙ্গেনি।
তবে স্পষ্টতই এই যুক্তিটি কোনওভাবে ভুল, এবং এমন অন্যান্য পরিস্থিতি রয়েছে যেখানে এই সীমাবদ্ধতার প্রয়োজন হবে।
আসুন বলি যে উত্তরগুলি C ++ 11 বা আরও নতুন (আমি বর্তমানে সি ++ 17 ব্যবহার করছি) এর জন্য হওয়া উচিত।
(1) দ্রষ্টব্য: EBO সি ++ 11 এ আপগ্রেড হয়েছে এবং বিশেষত এসগুলির জন্য বাধ্যতামূলক হয়ে উঠেছে StandardLayoutType
(যদিও Bar
উপরে, এটি একটি নয় StandardLayoutType
)।
Base *a = new Bar(); Base *b = a->foo;
হয়a==b
তবে আমাদের সাথে থাকতে পারে , তবেa
এবংb
স্পষ্টতই পৃথক অবজেক্ট (সম্ভবত বিভিন্ন ভার্চুয়াল পদ্ধতিতে ওভাররাইড সহ)।