Почему размер класса затрагивается, когда он содержит только виртуальную функцию? - PullRequest
0 голосов
/ 30 сентября 2011
class classWithNoVirtualFunction
{
    public:
        int   a;
        void x () 
        {
            char c;
            c = 'a';
        }
};

class classWithOneVirtualFunction
{
public:
   int          a;
   virtual void x () {}
};

class classWithTwoVirtualFunctions
{
public:
   int          a;
   virtual void x () {}
   virtual void y () {}
};

int main() 
{
   cout << "\nclassWithNoVirtualFunction's size: "   << sizeof (classWithNoVirtualFunction);    
   cout << "\nclassWithOneVirtualFunction's size: "  << sizeof (classWithOneVirtualFunction);
   cout << "\nclassWithTwoVirtualFunctions's size: " << sizeof (classWithTwoVirtualFunctions);

   cout << "\nvoid*'s size : " << sizeof (void*);
} 

W.R.T код выше, думая в C ++ говорит:

В этом примере требуется хотя бы один элемент данных. Если бы не было членов данных, компилятор C ++ заставил бы объекты быть ненулевой размер, потому что каждый объект должен иметь отдельный адрес. если ты представьте себе индексирование в массив объектов нулевого размера, вы будете Понимаю. «Пустышка» вставляется в объекты, которые в противном случае будет нулевого размера.

Мой вопрос: Теперь я не могу понять, что и как именно происходит, если у нас есть класс с нулевыми членами и виртуальная функция. Пожалуйста, объясните с некоторыми примерами программирования.

Ответы [ 2 ]

5 голосов
/ 30 сентября 2011

Всякий раз, когда класс содержит хотя бы одну виртуальную функцию, компилятору необходимо добавить информацию о типе RunTime для каждого из объектов. Реализация обычно добавляет один указатель на каждый объект, который ссылается на структуру, определенную компилятором и скрытую от пользователей, с указателем на объект type_info и vtable, используемым для динамической отправки функций.

В случае класса без нестатических элементов данных и, по крайней мере, одной виртуальной функции, размер каждого объекта равен размеру информации RTTI для каждого объекта (один указатель), и потому что это ненулевое значение , компилятор не будет добавлять дополнительное пространство. Цитата говорит, что sizeof(T) != 0 для любого и всех типов T, и тип с динамической функцией тривиально соответствует этому требованию. Только с типами, которые имеют нулевой размер, компилятор вынужден увеличивать объект на 1 символ.

0 голосов
/ 30 сентября 2011

Стандарт C ++ не определяет полную структуру класса. Это зависит от поставщика компилятора. Но стандарт C ++ дает некоторые гарантии. Например, размер законченного объекта всегда больше нуля. Причина этого правила намекается на текст, который вы цитировали в статье «Мышление в C ++». Виртуальные функции простого класса обычно реализуются в виде дополнительного скрытого члена-указателя, который идентифицирует динамический тип объекта, чтобы можно было вызывать правильную функцию динамического типа объекта. Поскольку этот дополнительный скрытый член добавляет к размеру класса, компилятору не нужно помещать туда какие-либо отступы, чтобы класс имел ненулевой размер.

Но это в основном детали реализации, о которых вам не стоит слишком беспокоиться. Пока вы полагаетесь только на гарантии, которые дает стандарт C ++, с вами все будет в порядке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...