Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.191.43.140] |
|
Сообщ.
#1
,
|
|
|
|
Сообщ.
#2
,
|
|
|
Еще одно дополнение - отличие в поведении при простом объявлении и через оператор new. Иллюстрирую кодом:
#include <stdio.h> typedef struct tag_s { int a; int b; } s; class c : public s { public: c() { a = 0; b = 0; } operator s(){ return *this; } }; class cni : public s { public: cni() { } operator s(){ return *this; } }; void Dump(s& t, const char* d){ printf("%5s: %8d %8d\n", d, t.a, t.b); } int main(void) { cni cni1; s s1; c c1; Dump(c1, "c1"); Dump(cni1, "cni1"); Dump(s1, "s1"); cni *pcni = new cni; s *ps = new s; c *pc = new c; Dump(*pc, "pc"); Dump(*pcni, "pcni"); Dump(*ps, "ps"); delete pcni; delete ps; delete pc; return 0; } Результат: c1: 0 0 cni1: 2048 0 s1: 2048 4 pc: 0 0 pcni: 0 0 ps: 0 0 Как видно, только для класса с определенным конструктором инициализация происходит и при объявлении, и при создании экземпляра через new. Для структуры и производного от нее класса - только при создании через new. |
Сообщ.
#3
,
|
|
|
Цитата barazuk @ Как видно, только для класса с определенным конструктором инициализация происходит и при объявлении, и при создании экземпляра через new. Для структуры и производного от нее класса - только при создании через new. Неправильный вывод. Никакой инициализации в строке s *ps = new s; не делается. Тебе просто повезло, что operator new вернул обнуленную память. Для гарантии, что члены такой структуры будут обнулены, надо писать s *ps = new s(); Про инициализацию cni - тут вообще нет инициализации, т.к. конструктор, вызываемый в любом случае, ничего инициализирующего тут не делает. И это никаким боком к рассматриваемой теме не относится. |
Сообщ.
#4
,
|
|
|
А если есть простой пользовательский конструктор?
Например: struct Point { Point(int _x, int _y) :x(_x), y(_y) { } int x; int y; }; Он введен для удобства - чтобы не писать несколько строк присваиваний для инициализации структуры Это POD-тип или нет? |
Сообщ.
#5
,
|
|
|
Цитата grustnoe @ А если есть простой пользовательский конструктор? К сожалению, не-POD , если следовать букве закона, то бишь Стандарта. Фактически, я не встречался с компиляторами, которые как-то меняли представление объекта при добавлении такого элементарного конструктора. Но это не значит, что их нет... |
Сообщ.
#6
,
|
|
|
Цитата grustnoe @ Это POD-тип или нет? нет |
Сообщ.
#7
,
|
|
|
Цитата grustnoe @ Он введен для удобства - чтобы не писать несколько строк присваиваний для инициализации структуры А чем тебя (в таком случае) не устраивает инициализация в стиле "С": Point pt = {1, 2}; |
Сообщ.
#8
,
|
|
|
Цитата Flex Ferrum @ чем тебя (в таком случае) не устраивает инициализация в стиле "С": не всегда удобно так писать, очень не всегда, например при возврате из функции getZeroPoint или передачи в функцию. Самого "убивала", такая мелочь. Самый простой выход написать функцию TPoint Point( int, int ); // сразу бросается в глаза неудобство создания POD структуры без каких бы то небыло префиксов. |
Сообщ.
#9
,
|
|
|
Цитата Hryak объектные типы и все остальные (к этим остальным относятся функции, ссылки и тип void. Грубо говоря, это типы, которые нельзя «пощупать», например, нельзя узнать их размер с помощью операции sizeof Поправочка: sizeof можно применять к любым типам-ссылкам на объектные типы (хотя типы-ссылки объектными типами действительно не являются). |
Сообщ.
#10
,
|
|
|
Применять-то sizeof можно. Но нельзя узнать размер "типа-ссылки". Т.е. sizeof(Type&) тоже самое, что sizeof(Type).
|
Сообщ.
#11
,
|
|
|
Цитата LPBOY @ Применять-то sizeof можно. Но нельзя узнать размер "типа-ссылки". Т.е. sizeof(Type&) тоже самое, что sizeof(Type). Как это понимать? У большинства типов-ссылок есть размер. Под этим размером понимается размер соответствующего типа-нессылки. А под размером типа-нессылки понимается размер объекта этого типа. Есть довольно практичный синоним понятия «объект» – всякая сущность, которая может быть элементом массива. |
Сообщ.
#12
,
|
|
|
Цитата Unreal Man @ У большинства типов-ссылок есть размер. Под этим размером понимается размер соответствующего типа-нессылки. Как тогда ты объяснишь, что у меня размер такой структуры struct A { int i; const double &r; A():r(1.0){} }; равен 8-ми, тогда как sizeof(int) + sizeof(double) = 4 + 8 = 12 В большинстве реализаций ссылки реализуются посредством указателей и соответственно занимают такой же объем памяти. Хотя в стандарте все же написано "It is unspecified whether or not a reference requires storage". Тот факт, что sizeof(T&)===sizeof(T) объясняется лишь тем, что любые действия над ссылками сводятся к действиям над объектами, на которые они ссылаются. Цитата Unreal Man @ Есть довольно практичный синоним понятия «объект» – всякая сущность, которая может быть элементом массива. Как насчет объектов таких классов std::type_info, struct A { A(int){} }; , struct B { private: B(){} }; |
Сообщ.
#13
,
|
|
|
Цитата LPBOY @ Как тогда ты объяснишь Размер типа-ссылки не равен физическому размеру объявляемой под этим типом сущности. По сути ты апеллируешь к понятию физического размера, но ведь он присущ лишь объекту. А что такое тип? Тип – это абстракция, у которой не может быть физического размера. Тем не менее, как и для других абстракций, для типа ради удобства можно ввести формальное понятие – в данном случае понятие размера. Цитата LPBOY @ Тот факт, что sizeof(T&)===sizeof(T) объясняется лишь тем, что любые действия над ссылками сводятся к действиям над объектами, на которые они ссылаются. Именно так. Но давай всё же зададимся таким вопросом: как удобнее называть то, что получается, когда мы применяем оператор sizeof к типу-ссылке: «результат применения оператора sizeof» или же «размер»? Цитата LPBOY @ Как насчет объектов таких классов Подразумевалась лишь возможность объявления массива объектов, реальное же существование объектов в составе массива в run-time не рассматривалось. Возможно, более правильно было бы говорить об объектных типах, а не о самих объектах, но у меня что-то не получается это нормально сформулировать применительно к типам struct C { std::type_info arr1[2]; A arr2[2]; B arr3[2]; }; Ты можешь определить такую структуру, это вполне законно. Можно сказать, что arr1 – это массив, элементы которого имеют тип std::type_info. Сущности же необъектных типов не могут быть элементами массива. Т.е. не может быть массива функций и ссылок – такие объявления будут некорректными (ну а сущностей типа void вообще не бывает, что уже говорить про массивы таких сущностей...). Реальную практическую пользу представляет из себя следующий код: template <class T> class IsObject { template <class T_> static char (&Check(...)) [1]; template <class T_> static char (&Check(T_(*)[1])) [2]; public: static const bool value = sizeof Check<T>(0) - 1; }; Этот класс предназначен для того, чтобы определять принадлежность типа T к объектным типам. Если T – объектный тип, то типы T[1] и T(*)[1] являются корректно составленными, и тогда выбирается вторая функция. Если же тип T – необъектный, то T(*)[1] не является корректно составленным типом, и, как следствие, выбирается функция с эллипсисом. |
Сообщ.
#14
,
|
|
|
Цитата Unreal Man @ По сути ты апеллируешь к понятию физического размера, но ведь он присущ лишь объекту. А что такое тип? Тип – это абстракция, у которой не может быть физического размера. Я и говорил о размерах объектов, а не типов. Запись sizeof(Type) означает "размер объекта типа Type", а не "размер типа Type". Кстати сравни свои аргументы: 1."У большинства типов-ссылок есть размер." 2. "Тип – это абстракция, у которой не может быть физического размера." Противоречия не замечаешь? Цитата Unreal Man @ Именно так. Но давай всё же зададимся таким вопросом: как удобнее называть то, что получается, когда мы применяем оператор sizeof к типу-ссылке: «результат применения оператора sizeof» или же «размер»? Это к чему? Цитата Unreal Man @ Подразумевалась лишь возможность объявления массива объектов, реальное же существование объектов в составе массива в run-time не рассматривалось. У меня именно ошибки времени компиляции, никакого рантайма. Цитата Unreal Man @ Ты можешь определить такую структуру, это вполне законно. ... Этот класс предназначен для того, чтобы определять принадлежность типа T к объектным типам. ... Хорошо, но все это в лучшем случае критерий определения объектных типов, но никак не "синоним понятия «объект»". Напомню с чего началась эта дискуссия: Hryak > нельзя узнать их (необъектные типы) размер с помощью операции sizeof Unreal Man > Поправочка: sizeof можно применять к любым типам-ссылкам на объектные типы У слов "узнать" и "применять" разный смысл. |
Сообщ.
#15
,
|
|
|
Что-то мне этот мелочный терминологический спор уже надоел...
Цитата LPBOY @ Запись sizeof(Type) означает "размер объекта типа Type", а не "размер типа Type". С такой трактовкой получается, что здесь Цитата Hryak @ Грубо говоря, это типы, которые нельзя «пощупать», например, нельзя узнать их размер с помощью операции sizeof Hryak попросту лил воду, ибо размер вообще никакого типа нельзя узнать, поскольку понятия размера для типа якобы не существует. Но давай почитаем тот же стандарт: Цитата ISO/IEC 14882:2003(E) §5.3.3 Sizeof When applied to a reference or a reference type, the result is the size of the referenced type. Значит, понятие размера для типа всё же имеет место, не так ли? И поэтому можно говорить, что sizeof(Type) означает «размер типа Type», что в свою очередь означает «размер объекта типа Type» (если речь идёт об объектном типе). Цитата LPBOY @ 1."У большинства типов-ссылок есть размер." 2. "Тип – это абстракция, у которой не может быть физического размера." Противоречия не замечаешь? Нет, не замечаю. Цитата LPBOY @ Это к чему? Ты никогда не задумывался, для чего существует такая штука, как терминология? |