c++ - প্যাডিং এবং উত্তরাধিকার বিষয়ে ক্লাস এবং struct মধ্যে পার্থক্য




c++11 gcc (2)

আপনার বেস বর্গের সাথে আপনি লেবেল প্যাডিংয়ের 4 বাইট এবং ডেরিভেড শ্রেণির সাথে একই পাবেন, এটি সাধারণত প্রাপ্তির আকারের জন্য মোট 24 bytes হওয়া উচিত।

এটি 16 বাইট হয়ে যায়, কারণ আপনার কম্পাইলার পুচ্ছ প্যাডিং পুনঃব্যবহার করতে সক্ষম।

তবে লেইলের প্যাডিং পুনঃব্যবহারটি POD প্রকারের (সমস্ত সদস্য সর্বজনীন, ডিফল্ট কনস্ট্রাক্টর, ইত্যাদি ...) সহ সমস্যাযুক্ত, কারণ এটি একটি প্রোগ্রামার তৈরি করে এমন সাধারণ অনুমানগুলি ভাঙ্গায়। (তাই মূলত কোন Sane কম্পাইলার পুড ধরনের জন্য পুচ্ছ প্যাডিং পুনঃব্যবহার করবেন না)

আসুন কম্পাইলার POD প্রকারের জন্য লেইলের tail padding reuse ব্যবহার করে বলি:

struct Base {
    double foo;
    int bar;
};

struct Derived : Base {
    int baz;
};

int main(int argc, char** argv)
{
    // if your compiler would reuse the tail padding then the sizes would be:
    // sizeof(Base) == 16
    // sizeof(Derived) == 16

    Derived d;
    d.baz = 12;
    // trying to zero *only* the members of the base class,
    // but this would zero also baz from derived, not very intuitive
    memset((Base*)&d, 0, sizeof(Base));

    printf("%d", d.baz); // d.baz would now be 0!
}

বেস বর্গের জন্য একটি স্পষ্ট কন্সট্রাকটর যুক্ত করার সময়, বা struct কীওয়ার্ডগুলি class পরিবর্তন করে, Derived শ্রেণিটি আরওডি সংজ্ঞাটি সন্তুষ্ট করে না এবং তাই লেইলের প্যাডিং পুনঃব্যবহার ঘটবে না।

নিচের সবগুলি GCC 9.1 -এ কম্পাইলার এক্সপ্লোরার ব্যবহার করে, x86-64 এ, -O3 ব্যবহার করে করা -O3

আমার এই কোড আছে:

struct Base {
    Base() {}
    double foo;
    int bar;
};

struct Derived : public Base {
    int baz;
};

int main(int argc, char** argv)
{
    return sizeof(Derived);
}

https://godbolt.org/z/OjSCZB

এটি সঠিকভাবে 16 , যেমন আমি আশা করি, ফু জন্য 8 বাইট, এবং bar জন্য 4 বাইট এবং baz জন্য 4 বাইট। এটি কেবলমাত্র Base থেকে Derived উত্তরাধিকারসূত্রে Derived কারণ এবং তাই এটি Derived এবং Derived উপাদানগুলি সমন্বিত একটি একক টাইপের কারণে bar পরে প্যাড করতে হবে না।

আমার নিচে দুটি প্রশ্ন আছে:

প্রথম প্রশ্ন

যদি আমি Base() {} এর সুস্পষ্ট কন্সট্রাকটরটি মুছে ফেলি, তবে এটি 16 পরিবর্তে 24 টি ফিরে শুরু করে। অর্থাৎ এটি bar এবং baz পরে প্যাডিং যোগ করে।

https://godbolt.org/z/0gaN5h

একটি স্পষ্ট ডিফল্ট কন্সট্রাকটর থাকা কোনও অন্তর্নির্মিত ডিফল্ট কন্সট্রাকটর থাকার জন্য ভিন্ন কেন আমি ব্যাখ্যা করতে পারছি না।

দ্বিতীয় প্রশ্ন

যদি আমি Base জন্য struct পরিবর্তন করি, তবে এটি 16 ফিরে যাওয়ার জন্য পরিবর্তন করে। আমি এই ব্যাখ্যা করতে পারেন না। কেন অ্যাক্সেস modifiers গঠন আকার পরিবর্তন হবে?

https://godbolt.org/z/SCYKwL


এই সব আপনার টাইপ একটি সমষ্টিগত বা না কিনা নিচে boils। সঙ্গে

struct Base {
    Base() {}
    double foo;
    int bar;
};

struct Derived : public Base {
    int baz;
};

Base নির্মাতা কারণে একটি সমষ্টিগত নয়। যখন আপনি কন্সট্রাকটরটি সরিয়ে ফেলেন, আপনি .com/q/47914612/560648 একটি সমষ্টিগত করে তুলেন যা, .com/q/47914612/560648 , অর্থাত gcc স্পেসের জন্য "অপ্টিমাইজ" করবে না এবং উদ্ভূত বস্তু বেসটির লেইস প্যাডিং।

আপনি কোড পরিবর্তন যখন

class Base {
    double foo;
    int bar;
};

struct Derived : public Base {
    int baz;
};

foo এবং bar এখন ব্যক্তিগত (কারণ ক্লাসগুলি ডিফল্টরূপে ব্যক্তিগত অ্যাক্সেসযোগ্যতা আছে) যার অর্থ আবার Base সমষ্টিগত নয় কারণ সমষ্টিগুলি ব্যক্তিগত সদস্যদের জন্য অনুমোদিত নয়। এর মানে হল আমরা কিভাবে প্রথম কেস কাজ করে ফিরে।







gcc