- 1
- 2
- 3
- 4
Class1* c1 = (Class1*)malloc(sizeof(Class1)*N);
Class2* c2 = (Class2*)malloc(sizeof(Class2)*N);
for (long i = 0; i < N; i++) c1[i] = Class1();
for (long i = 0; i < N; i++) c2[i] = Class2();
Нашли или выдавили из себя код, который нельзя назвать нормальным, на который без улыбки не взглянешь? Не торопитесь его удалять или рефакторить, — запостите его на говнокод.ру, посмеёмся вместе!
+19
Class1* c1 = (Class1*)malloc(sizeof(Class1)*N);
Class2* c2 = (Class2*)malloc(sizeof(Class2)*N);
for (long i = 0; i < N; i++) c1[i] = Class1();
for (long i = 0; i < N; i++) c2[i] = Class2();
Рассказать ему про new[] / delete[]?
bormand 29.11.2012 20:14 # +7
ForEveR 30.11.2012 09:33 # +2
bormand 30.11.2012 09:54 # +2
Во-вторых - чтобы подчеркнуть низкоуровневость творимого здесь хаоса.
В третьих - потому что так короче чем (T*)new char[sizeof(T)*poolSize], и уж точно короче и понятней, чем (T*)operator new[](sizeof(T)*poolSize), которые один хрен вызовут тот же самый malloc.
P.S. Предвижу следующий вопрос - "почему сишный каст?".
ForEveR 30.11.2012 10:01 # +2
bormand 30.11.2012 10:15 # +3
Да, и это еще одна причина использовать тут malloc - даже если кто-то перегрузил operator new[](size_t), код не будет им пользоваться ;)
P.S. Можно и системнозависимыми средствами в духе VirtualAlloc страничку выделить, если задача того требует. Или даже в заmmap'ленном куске организовать этот пул... Хотя и operator new[]() имеет полное право на жизнь, все зависит от задачи.
Про static_cast согласен.
ForEveR 30.11.2012 14:31 # +1
Да конечно. Только стандарт тоже не гарантирует, что будет вызван malloc. С тем, что все зависит от задачи абсолютно согласен.
bormand 30.11.2012 15:08 # +1
Согласен. Сейчас даже фразу об этом в нем нашел: Whether the attempt involves a call to the Standard C library function malloc is unspecified.
guest 30.11.2012 22:42 # −9
ForEveR 30.11.2012 23:13 # +1
bormand 01.12.2012 00:25 # +2
Здесь сказано только о том, что new может не вызывать malloc, а пользоваться другими механизмами.
someone 30.11.2012 00:04 # +3
Расскажите, что он вызывает operator= для неинициализированных объектов, у которых даже конструктор не вызывался.
bormand 30.11.2012 08:47 # 0
Steve_Brown 30.11.2012 09:44 # +2
bormand 30.11.2012 09:48 # +3
Psionic 01.12.2012 02:15 # 0
bormand 01.12.2012 08:49 # +1
Psionic 01.12.2012 16:55 # 0
Setry 01.12.2012 21:20 # 0
Psionic 01.12.2012 22:18 # 0
http://ideone.com/E4U378
bormand 01.12.2012 22:35 # +1
Не в каждом. Только в тех, где есть хотя бы 1 виртуальный метод. По этой причине, кстати, RTTI не пашет на таких классах, и static_cast<T*>(a) может вернуть другой адрес даже без множественного наследования.
А виртуальные функции тут нельзя из-за memset'а, который уничтожит указатель на таблицу.
P.S. Не помню, пишется ли этот указатель перед конструктором или после... Надо пошариться в стандарте.
bormand 01.12.2012 22:51 # 0
http://ideone.com/Zi6Osl
guest 01.12.2012 22:55 # +1
guest 01.12.2012 23:03 # 0
http://ideone.com/zuoO3y
absolut 02.12.2012 08:43 # 0
bormand 02.12.2012 09:02 # +3
Setry 02.12.2012 09:05 # 0
Но мне кажется, что в стандарте ничего не прописано о порядке инициализации vptr и именно поэтому вызов виртуальных функций из конструктора не есть хорошо.
absolut 02.12.2012 09:14 # 0
Setry 02.12.2012 09:27 # 0
под фразой "порядок инициализации" я имел ввиду "перед конструктором или после него"
Да, и с формальной точки зрения. Я - базовый класс, у меня есть свой vptr и мне пофиг из какого производного класса я создаюсь. Так что аргумент " экземпляр дочернего класса еще не создан" не подходит.
absolut 02.12.2012 09:38 # +2
bormand 02.12.2012 10:29 # 0
absolut 02.12.2012 10:40 # +2
bormand 02.12.2012 11:13 # +4
Т.е. виртуальный вызов из конструктора или деструктора делать можно, и работает он так, как будто от текущего класса ничего не порождено. Что в общем то логично. И получается, что vptr текущего класса запихивается непосредственно перед вызовом его конструктора, а откатывается на родительский после выхода из деструктора (иначе стандарт бы указал, что вызов виртуалок из конструктора/деструктора это UB).
P.S. Но т.к. при этом конструктор еще не доработал, часть полей могут быть недоинициализированными, поэтому так делать нежелательно.