Комментарии 40
Есть замечание по терминологии.
Во-первых, отличить на глаз «оператор» от «operator» в потоке текста очень сложно (особенно тем, кто много читает на английском). Во-вторых, раз уж вы пытаетесь рассмотреть разницу между этими понятиями, называть их одним и тем же словом неразумно. Можно окончательно запутать читателя. Конечно, и statement можно перевести как «оператор», но лучше не надо. Это не «лирика», а важное различие на уровне компилятора. (Пишу не в личные сообщения, потому что вопрос спорный и подлежит обсуждению.)
Для начала опеределимся с терминологией — далее именуемый в стандарте new-expression я буду называть «оператор new» (...), а operator new я так и буду называть operator new. (...)
оператор new — это оператор языка, такой же как if, while и т.д. (хотя if, while и т.д. все же именуются как statement, но отбросим лирику)
Во-первых, отличить на глаз «оператор» от «operator» в потоке текста очень сложно (особенно тем, кто много читает на английском). Во-вторых, раз уж вы пытаетесь рассмотреть разницу между этими понятиями, называть их одним и тем же словом неразумно. Можно окончательно запутать читателя. Конечно, и statement можно перевести как «оператор», но лучше не надо. Это не «лирика», а важное различие на уровне компилятора. (Пишу не в личные сообщения, потому что вопрос спорный и подлежит обсуждению.)
Можно было, например, опустить слово «оператор/operator». Все равно дальше по тексту одна из форм всегда используется со скобками, другая — без них.
Согласен, исправлю.
В наиболее распространенном русском переводе «The C++ Programming Language» этой теме был посвящен довольно-таки большой параграф во вступлении от переводчиков. В той книге они использовали для перевода «statement» слово «инструкция». Я думаю, достаточно большое количество русскоговорящих разработчиков на C++ начинали именно с этой книги, или, во всяком случае, читали её на каком-то этапе — так что в плане терминологии её можно использовать как некоторого рода стандарт.
Статья конечно может «как-то» помочь новичкам.
Но! Не знаю о каких книгах вы говорите (судя по всему о дейтелах и им подобных), но в Мейерсе, Саттере, Дьюхерсте, Вилсоне и даже в Джосютиссе (не представляю какие еще книги по С++ можно читать, ну кроме Страуструпа конечно) четко разделяется оператор new от выражения new.
Думаю (это критика, которую вы хотели) вы просто только что открыли для себя Америку и хотели раксрыть «заговор» всему миру, но мир еще десять лет назад знал об этом ка свои пять пальцев.
P. S. Ставлю плюс, чтоб не разбить стремление к sharing-у знаний.
Но! Не знаю о каких книгах вы говорите (судя по всему о дейтелах и им подобных), но в Мейерсе, Саттере, Дьюхерсте, Вилсоне и даже в Джосютиссе (не представляю какие еще книги по С++ можно читать, ну кроме Страуструпа конечно) четко разделяется оператор new от выражения new.
Думаю (это критика, которую вы хотели) вы просто только что открыли для себя Америку и хотели раксрыть «заговор» всему миру, но мир еще десять лет назад знал об этом ка свои пять пальцев.
P. S. Ставлю плюс, чтоб не разбить стремление к sharing-у знаний.
>Не знаю о каких книгах вы говорите
Я же написал «в книгах для начинающих»
За критику спасибо, но не каждый С++'ник может «на пальцах» объяснить где и как вызывается конструктор при использовании new, поэтому
>мир еще десять лет назад знал об этом
считаю не совсем уместным. Мир то знал, а вот некоторые программисты до сих пор не знают)
Я же написал «в книгах для начинающих»
За критику спасибо, но не каждый С++'ник может «на пальцах» объяснить где и как вызывается конструктор при использовании new, поэтому
>мир еще десять лет назад знал об этом
считаю не совсем уместным. Мир то знал, а вот некоторые программисты до сих пор не знают)
:) Теперь будут знать, и еще будут знать какие книги читать ;)
не каждый С++'ник может «на пальцах» объяснить где и как вызывается конструктор при использовании new, поэтому
Этими знаниями можно блеснуть на собеседовании (но мне такой вопрос ни разу не задавали и я кажется знаю почему), но какой от них практический толк?
Ну вот не знаю я (или просто забыл) что operator new != keyword new, но я примерно помню (читал не раз) как переопределяется свой operator new. А теперь я знаю (вспомнил) что operator new != keyword new… и… ничего не изменилось, я все еще не знаю накой мне это может понадобится и тем более на какие грабли при этом я встану (я ведь знания как правильно переопределять operator new гораздо важнее чем знания, что operator new != keyword new).
Какой профит?
Какой профит?
В прикладном плане никакого. Но неужели не хочется знать чуть больше, чем необходимо? :)
А если включить мозг? И вспомнить, что и глобальный оператор можно только заменить, а локальный перегрузить как угодно?
А какое отношение это имеет к написанному в статье?
Трампарарам., вы говорите не знаете как применить на практике различие межу кейвордом и оператором. А я уже говорю, что оператор можно перегрузить как угодно. Уже только из этого вытекает масса различным применений.
А если заменить реализацию кейворда на свою, а оператор не трогать? А если сделать и то и другое?
А если заменить реализацию кейворда на свою, а оператор не трогать? А если сделать и то и другое?
> но мир еще десять лет назад знал об этом ка свои пять пальцев
тридцать лет назад :-)
тридцать лет назад :-)
Можно Джефферсона еще почитать) А об авторах, которых Вы перечислили даже не слышал, ну кроме Страуступа, конечно)
Имхо проще в русском тексте так и писать — «new-expression» и «operator new» вместо «оператор» и «operator».
Советую к прочтению: www.amse.ru/courses/cpp2/2011_03_21.html
Прочитав про две разные сущности, ожидал дальше увидеть два разных примера применения каждой из них. Но не увидел. Как можно воспользоваться этим различием между new-оператором и new-ключевым словом в процессе разработки?
Прочитав про две разные сущности, ожидал дальше увидеть два разных примера применения каждой из них.
Эм, здесь речь немного не об этом, пример реализации operator new() можно найти в любой книге, поэтому я не стал его включать в статью.
Как можно воспользоваться этим различием… в процессе разработки?
В процессе разработки, думаю, никак. Просто такие вещи полезно знать и понимать хотя бы для самого себя.
Ну не знаю, я бы привёл реализацию
становится ясно, что
operator new
(msvc10
):_C_LIB_DECL
int __cdecl _callnewh(size_t size) _THROW1(_STD bad_alloc);
_END_C_LIB_DECL
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{ // try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{ // report no memory
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
становится ясно, что
operator new
просто выделяет память, причём тем-же malloc
— при неудачном выделении памяти — вызывает new_handler
функцию и только потом (если ничего не изменилось) бросает исключение.1. Нигде не разделяют new key-word языка С++ и оператор new, везде о них говорят как об одной сущности.
Как это нигде, Мейерс разделяет, стандарт разделяет :-)
Как это нигде, Мейерс разделяет, стандарт разделяет :-)
Кстати, похожая ситуация с operator ->() и оператором ->, который для пользовательских типов преобразуется в:
(object.operator ->())->member
(object.operator ->())->member
Читаем «C++ For Real Programmers» (Jeff Alger) и ещё много нового о работе с памятью.
А при чем тут работа с памятью?
Ну это да, как и delete. Просто в статье речь не о работе с памятью и не об использовании new / delete.
Ну, new и operator new() предназначены — внезапно — для управления памятью. А в книге, которую я порекомендовал, помимо озвученного в статье материала, есть ещё куча информации об этих сущностях, а также об управлении памятью в C++ вообще. Информация в статье интересная, но сама по себе бесполезная, вот книга и даст остальную информацию, необходимую для того, чтобы, например, реализовать сборку мусора и дефрагментацию памяти.
Вроде банальный момент, который сразу всплывает когда в коде встречаются 'new int' и 'new Foo'.
у кого-нибудь корректно получалось в своей жизни хоть раз использовать placement syntax new для массивов?
у меня он так и не стал добавлять нужные оверхеды и пришлось везде юзать обычный placement syntax внутри цикла.
у меня он так и не стал добавлять нужные оверхеды и пришлось везде юзать обычный placement syntax внутри цикла.
А в чем проблема? У меня вроде все работало.
грубо говоря как то так работало:
T* pNew = (T*)m_BasicCallback->malloc_cb(sizeof(T)*size,1);
//copy old elements
T* raw_i = pNew;
int i=0;
for(;i<m_Size;++i,++raw_i){
raw_i = new (raw_i) T(m_pData[i]);
}
а вот какую-то запись которая бы и память корректно выделила и конструкторы для всех экземпляров массива вызвала не получилось. вариант для массивов памяти выделял почему-то меньше чем было нужно.
T* pNew = (T*)m_BasicCallback->malloc_cb(sizeof(T)*size,1);
//copy old elements
T* raw_i = pNew;
int i=0;
for(;i<m_Size;++i,++raw_i){
raw_i = new (raw_i) T(m_pData[i]);
}
а вот какую-то запись которая бы и память корректно выделила и конструкторы для всех экземпляров массива вызвала не получилось. вариант для массивов памяти выделял почему-то меньше чем было нужно.
Хм, вот такой пример:
Проблем в упор не вижу (Ну кроме того, что если вместо char будет класс, то придется делать прямой вызов деструктора, а потом делать free)
char *ptr = (char*) malloc(10);
memset(ptr, 1, 10);
char* ptrPlacement = new(ptr) char[10];
ptrPlacement[9]=10;
free(ptr);
Проблем в упор не вижу (Ну кроме того, что если вместо char будет класс, то придется делать прямой вызов деструктора, а потом делать free)
Для динамически созданной группы обьектов нельзя применять конструктор с параметрами.
Спасибо большое за статью! Для меня этот вопрос с оператором new создал путаницу в голове. Теперь все стало ясно.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
[C++] Всё ли мы знаем об операторах new и delete?