Нужен ли размер объекта для создания объекта в куче?

Когда компилятору необходимо знать размер объекта C (класса): например, при размещении C в стеке или в качестве непосредственно удерживаемого члена другого типа

Из Стандарты кодирования C++: 101 правило, рекомендации и рекомендации

Означает ли это, что для объекта, выделенного в куче, размер не нужен?

Class C;//just forward declaration
C * objc = new C();

person yesraaj    schedule 04.06.2009    source источник
comment
Вы спрашиваете о C++ или C? Пожалуйста, отредактируйте свой вопрос, чтобы уточнить это.   -  person    schedule 04.06.2009
comment
Кто ты в цитате? Вам, как программисту, почти никогда не нужно это знать. У компилятора есть. Я думаю, что в цитате отсутствует контекст до уровня, на котором невозможно ответить на ваш вопрос.   -  person Suma    schedule 04.06.2009
comment
На основе тегов (декларация, определение) эта цитата пытается объяснить, почему иногда тип нужно определять, а не только объявлять. Поэтому вы, скорее всего, компилятор.   -  person Suma    schedule 04.06.2009
comment
Приносим извинения за задержку ответа, qn сейчас в порядке?   -  person yesraaj    schedule 04.06.2009
comment
Форвардные объявления используются в заголовочных файлах, где нет выделений памяти. Вы должны включить полное определение класса перед выполнением распределения независимо от того, находится ли он в куче или стеке.   -  person Kieveli    schedule 04.06.2009


Ответы (6)


Чтобы ответить на ваш конкретный вопрос:

Означает ли это, что для размера объекта, выделенного в куче, нет необходимости?

Class C;//just forward declaration
C * objc = new C();

С++ не позволит вам сделать это.

Даже если бы вы могли выполнить 'new' для неполного типа, волшебным образом определив размер позже (я мог предположить, что это технически возможно при сотрудничестве с компоновщиком), попытка потерпит неудачу во время компиляции, по крайней мере, из-за 2 причины:

  1. оператор new можно использовать только с полными типами. Из стандарта С++ 98 5.3.4 - «[выделенный] тип должен быть полным типом объекта, но не типом абстрактного класса или его массивом»

  2. компилятор понятия не имеет, какие конструкторы существуют (и доступны), поэтому по этой причине он также должен потерпеть неудачу.

person Michael Burr    schedule 05.06.2009

Нет, этот список приведен в качестве примера, а не исключения. Очевидно, что размер объекта должен быть известен при распределении кучи, чтобы можно было выделить правильный объем памяти.

person Community    schedule 04.06.2009

Размер объекта вычисляется оператором new:

Object *o = new Object();

Вам не нужно явно указывать new размер объекта, но он вычисляет его (используя оператор sizeof), чтобы выделить правильное количество места в куче.

person Yuval Adam    schedule 04.06.2009
comment
Я считаю, что вопрос немного более точен в том смысле, что он, кажется, спрашивает, достаточно ли предварительного объявления для типа для создания объекта в куче. sizeof() вычисляется компилятором через знание типа и, следовательно, размера, вам не нужно это знать, но это должен знать компилятор. - person David Rodríguez - dribeas; 04.06.2009

Вам, как программисту, почти никогда не нужно знать размер объекта в C++. Например:

class A {
    ...  // member data
};

void f() {
    A a;              // allocate on stack
    A * p = new A;    // allocate on heap
}

Ни в том, ни в другом случае знание размера не требуется программисту - его, конечно, должен знать компилятор.

Обратите внимание, что как бы вы ни создавали объект, его размер должен быть известен компилятору в момент создания:

class B;     // forward declaration - no size:

void f() {
    B b;              // compilation error
    B * p = new B;    // compilation error
}
person Community    schedule 04.06.2009
comment
Неявно размер известен в обоих случаях. Просто не обязательно вами - но компилятор выдаст ошибку, если он не знает достаточно, чтобы это обработать - person 1800 INFORMATION; 04.06.2009

Нет. Чтобы разместить объект в куче, вы должны знать его размер.

Foo *foo=(Foo *)malloc(sizeof(*foo));
person 1800 INFORMATION    schedule 04.06.2009
comment
Вопрос помечен как C++, а не C. - person ; 04.06.2009
comment
Это допустимо в C++ - например, мы видим в исходном коде среды выполнения VS C++ новый оператор вызывает malloc для выделения памяти, поэтому размер известен неявно во время выделения. - person 1800 INFORMATION; 04.06.2009
comment
Даже тут вы как программист не знаете размер. Это компилятор, который это знает (вы спрашиваете и передаете ответ malloc) - person Suma; 04.06.2009
comment
Foo *foo=(Foo *)malloc(sizeof(Foo)); Кроме того, только потому, что один компилятор просто оборачивает malloc, не означает, что это делает другой. Кроме того, если у Foo есть конструктор, вы только что создали Foo, не запуская его. - person Dolphin; 04.06.2009
comment
Обычно я предполагаю, что если компилятор знает что-то от моего имени, это по сути то же самое, как если бы я знал это, даже если я на самом деле не выводил значение этой вещи на экран. Например, у нас может быть любое количество локальных переменных для вычисления временного значения — вам не нужно смотреть на значение в отладчике, чтобы сказать, что вы знаете это значение, вероятно, достаточно просто сослаться на эту переменную в вашем код. - person 1800 INFORMATION; 05.06.2009
comment
Помимо того, что я утверждал, что это был действительный C++, я действительно не хочу вступать в какую-то сократовскую дискуссию о значении слова «знать». Учитывая, что это допустимый C++, компилятор должен знать размер объекта независимо от того, выделяете ли вы объект в куче с помощью new или malloc или любого другого типа объекта. Я использую malloc здесь в качестве примера и явно показываю, что размер требуется - новая версия этого не показывает. - person 1800 INFORMATION; 05.06.2009

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

person David Rodríguez - dribeas    schedule 04.06.2009