2009-09-01 3 views
3

Для следующего фрагмента кода.sizeof для класса, наследующего базовый класс с виртуальной функцией

/*This program demonstartes how a virtual table pointer 
* adds to a size of a class*/ 

class A{ 

}; 

class X{ 
    public: 
     void doNothing(){} 
    private: 
     char a; 

}; 

class Z:public X { 

    public: 
     void doNothing(){} 
    private: 
     char z; 

}; 

class Y{ 
    public: 
     virtual void doNothing(){} 
    private: 
     char a; 

}; 

class P:public Y { 

    public: 
     void doNothing(){} 
    private: 
     char pp[4]; 

}; 

int main(){ 
    A a; 
    X x; 
    Y y; 
    Z z; 
    P p; 
    std::cout << "Size of A:" << sizeof(a) << std::endl;// Prints out 1 
    std::cout << "Size of X:" << sizeof(x) << std::endl;//Prints out 1 
    std::cout << "Size of Y:" << sizeof(y) << std::endl;//Prints 8 
    std::cout << "Size of Z:" << sizeof(z) << std::endl; 
//Prints 8 or 12 depending upon wether 4 bytes worth of storrage is used by Z data member. 
    std::cout << "Size of P:" << sizeof(p) << std::endl; 
    std::cout << "Size of int:" << sizeof(int) << std::endl; 
    std::cout << "Size of int*:" << sizeof(int*) << std::endl; 
    std::cout << "Size of long*:" << sizeof(long*) << std::endl; 
    std::cout << "Size of long:" << sizeof(long) << std::endl; 
    return 0; 

} 

поведение мне кажется, нужно заметить, что всякий раз, когда пустой класс инстанциируется или пустой класс наследуется от границы байта не считаются (то есть: объект размером 1 байт разрешено), в любом другом случае размер объекта, по-видимому, определяется границами байтов.

В чем причина этого? Я спрашиваю, с этого момента я догадываюсь.

+2

Я думаю, что вопрос заключается в следующем: «Почему компилятор, похоже, не заботится о выравнивании/заполнении для пустых классов? Например, почему пустой класс может быть 1 байт, но класс с только элементом char требует заполнения?» Заголовок вопроса все еще не является секвенсором, хотя –

+1

Вы извинились за запутанный вопрос. Теперь, пожалуйста, сделайте еще один шаг и * исправьте это. Вы приняли ответ, так что, возможно, вы можете отредактировать вопрос, чтобы он имел смысл в свете ответа. Например, вы упомянули о виртуальных функциях, но принятый ответ вообще не касается виртуальных функций, так как они действительно релевантны вашему вопросу? –

ответ

3

Здесь explanation: почему размер пустого класса не может быть равен нулю. Что касается того, почему это 1 байт, в отличие от того, что соответствует границам выравнивания, я предполагаю, что это зависит от компилятора.

6

Я не уверен, что речь идет о, но я сделаю дикое предположение и предположим, что вы смущены тем, что sizeof(A)==1, X производный от A добавив char поле, и в то же время (sizeof(X)==1 вы ожидаете, что он будет 2 - один для A, один для char в X).

Это называется «пустая оптимизация базового класса». В C/C++ объект должен иметь ненулевой размер (ISO C++ 1.8 [intro.object]/5) - это косвенно подразумевает, что каждый объект имеет отдельный адрес, независимо от объединения, поэтому даже для пустого класса он все еще должен быть не менее 1 байт. Однако, когда объектом является подобъект базового класса другого объекта, это ограничение снимается. Таким образом, экземпляр A должен быть не менее 1 байта сам по себе, но когда A является базовым классом другого класса, для этого больше нет требования, и компилятор полностью избавится от этого фиктивного заполнения; поэтому размер X происходит только от его поля char.

+0

Извините за нит, но у C нет объектов. Так что это должно быть «В C++, а объект должен иметь ненулевой размер ...» – Dima

+4

C имеет объекты. Однако в C и C++ термин «объект» не имеет ничего общего с ООП. Из раздела ISO C99, раздел 3 «Термины, определения и символы», подраздел 3.14: «объект - область хранения данных в среде исполнения, содержимое которой может представлять значения». ISO C++ использует аналогичное определение. Экземпляр класса в C++ является «объектом типа класса» (в то время как значение «int» является «объектом неклассического типа»). –

+0

Извините за ужасно запутанный вопрос. – Pradyot

Смежные вопросы