Что делает оператор
Недавно был сильно удивлён, когда узнал, что многие backend разработчики middle уровня в крупных компаниях не знают, что делает ключевое слово
Конечно, верхнеуровневая концепция в рамках ООП понятна. Создаём объект, заносим какие-то параметры, значения присваиваются и получается связка некоторых данных под именем одного типа.
Однако, отсутствует низкоуровневое понимание процесса.
То есть, что делать, если в языке нет этого слова
Здесь нам поможет обращение к истокам, а именно языку программирования Си.
На его примере очень полезно изучать концепцию динамической памяти и указателей.
Правда делать надо это осторожно, иначе не избежать часов с valgrind.
Так вот память, требуемая для создания объекта выделяется динамически.
Что это значит?
Компилятор во время своей работы не может определить в какой области памяти будут лежать данные, понадобится ли память для них вообще, а в некоторых случаях и сколько потребуется.
Всю эту информацию можно получить только во время выполнения программы.
Соответственно, в Си для этого были добавлены:
▪️ключевое слово
▪️функции выделения памяти (аллокации):
▪️функция освобождения памяти:
Пользуясь этими конструкциями можно описать примитивное поведение оператора
Например, у нас есть структура точки
Если на чём-то вроде Java мы напишем:
То есть, мы посчитали, сколько нам надо памяти, выделили её и вернули указатель на адрес, по которому лежит созданный объект.
А уже через него можно заниматься инициализацией, обновлением, и так далее.
new
?Недавно был сильно удивлён, когда узнал, что многие backend разработчики middle уровня в крупных компаниях не знают, что делает ключевое слово
new
.Конечно, верхнеуровневая концепция в рамках ООП понятна. Создаём объект, заносим какие-то параметры, значения присваиваются и получается связка некоторых данных под именем одного типа.
Однако, отсутствует низкоуровневое понимание процесса.
То есть, что делать, если в языке нет этого слова
new
?Здесь нам поможет обращение к истокам, а именно языку программирования Си.
На его примере очень полезно изучать концепцию динамической памяти и указателей.
Правда делать надо это осторожно, иначе не избежать часов с valgrind.
Так вот память, требуемая для создания объекта выделяется динамически.
Что это значит?
Компилятор во время своей работы не может определить в какой области памяти будут лежать данные, понадобится ли память для них вообще, а в некоторых случаях и сколько потребуется.
Всю эту информацию можно получить только во время выполнения программы.
Соответственно, в Си для этого были добавлены:
▪️ключевое слово
sizeof
, определяющее количество байтов, необходимое для хранения типа▪️функции выделения памяти (аллокации):
malloc
, calloc
, realloc
▪️функция освобождения памяти:
free
Пользуясь этими конструкциями можно описать примитивное поведение оператора
new
.Например, у нас есть структура точки
Point
:
struct Point {
float x, y;
};
Если на чём-то вроде Java мы напишем:
var p = new Point()
, то на Си это будет выглядеть так:
struct Point *p = (struct Point*)malloc(sizeof(struct Point));
// обязательно потом высвобождаем память, ведь GC у нас нет!
free(p);
То есть, мы посчитали, сколько нам надо памяти, выделили её и вернули указатель на адрес, по которому лежит созданный объект.
А уже через него можно заниматься инициализацией, обновлением, и так далее.