Різниця між "новим оператором" та "новим оператором"?


126

Чим відрізняється "новий оператор" від "оператор новий"?


3
Привіт, ви можете, будь ласка, уточнити питання? Схоже, десь є друкарня.
Діма Маленко

17
Питання сформульовано правильно, див. Відповіді нижче. Метод динамічного розподілу пам’яті полягає у використанні newоператора. Цей оператор може бути перевантажений. Для розмежування оператора за замовчуванням і перевантаженої версії за замовчуванням називається "новий оператор", а перевантажена версія називається "оператор новий".
Томас Меттьюз

2
Як це зробити. Я новий і не знаю.
Сандіп

Відповіді:


127

Я, як правило, намагаюся по-різному сформулювати речі, щоб розрізнити обидва, але це питання добре в будь-якому випадку.

Operator new - це функція, яка виділяє необроблену пам'ять - принаймні концептуально, вона не сильно відрізняється від malloc(). Хоча це досить незвично, якщо ви не пишете щось на зразок власного контейнера, ви можете зателефонувати безпосередньо новому оператору, наприклад:

char *x = static_cast<char *>(operator new(100));

Можливо також перевантажити нового оператора або глобально, або для конкретного класу. IIRC, підпис:

void *operator new(size_t);

Звичайно, якщо ви перевантажуєте нового оператора (глобального або для класу), вам також буде потрібно / перевантажити видалення відповідного оператора. Для того, що варто, є також окремий оператор new [], який використовується для розподілу пам'яті для масивів - але вам майже напевно краще повністю ігнорувати весь цей безлад.

Новий оператор - це те, що ви зазвичай використовуєте для створення об'єкта з безкоштовного магазину:

my_class *x = new my_class(0);

Різниця між ними полягає в тому, що оператор new просто виділяє необроблену пам'ять, нічого іншого. Новий оператор починає з використання оператора new для розподілу пам'яті, але потім він викликає конструктор для потрібного типу об’єкта, тому результат - це реальний живий об'єкт, створений у цій пам'яті. Якщо цей об'єкт містить будь-які інші об'єкти (вбудовані або як базові класи), ці конструктори також викликаються.


18
+1, що стосується іншого фразування, стандарт використовує новий вираз усе навколо, і лише один раз він використовує нового оператора для позначення місця виклику. Я схильний робити те саме: новий оператор для розподільника та новий вираз для використання.
Девід Родрігес - дрибес

3
Новий вираз - це вся фраза, яка починається з нової. То що ви називаєте просто "новою" його частиною? Якщо неправильно називати нового оператора, ми не повинні називати "sizeof" розміром оператора, або & адресою оператора (коли він поводиться як один).
Каз

1
Виходячи із зауваження Каза, можливо, питання слід переосмислити так: Яка різниця між новим оператором і новим оператором оператора? :)
CS

2
"Оператор новий" проти "Нове ключове слово"
user997112

2
@antred: Ви випустите це з чимось подібним operator delete(x);.
Джеррі Труну

35

"оператор новий"

class Foo
{
public:
        void* operator new( size_t );
}

"новий оператор":

Foo* foo = new Foo();

У цьому прикладі new Foo()дзвінкиFoo::operator new()

Іншими словами, "новий оператор" дзвонить " operator new()" так само, як дзвонить операторoperator +()


13
newне є оператором на C ++. sizeof, Наприклад, є оператором, але newі deleteне є. newі deleteце ключові слова та синтаксичні конструкції, які ці ключові слова утворюють називаються новим виразом та видаленням-виразом .
ANT

2
Ну, якщо що, sizeofє синтаксичною конструкцією, newі deleteвони є обома дійсними, законними операторами, здатними перевантажувати. З усього, що я коли-небудь бачив, newі deleteє обома операторами. Дивіться [cplusplus.com] [ cplusplus.com/doc/tutorial/classes2/]
Остін Гайд

7
Неправильно. Офіційна термінологія C ++ - це термінологія, визначена мовною специфікацією, а не деяким веб-сайтом. У специфікації мови немає такого терміна, як "новий оператор", але існує такий термін, як " operator newфункція". Знову ж , sizeofце explicilty називають «оператора», в той час як newі deleteНЕ разу не називають операторами.
ANT

6
АндрейТ: Неправильно. Стандарт C ++ дійсно викликає "нового" оператора, див. 13.5 / 1.

3
@AndreyT: Я думав, як і ти, що новий оператор - це розподільник і новий вираз використання. Я переглянув і перевірив, що в §5.3.4 / 3 в поточному стандарті використовується термін новий оператор . Пізніше в §5.3.4 / 8 він називає функції розподільника як нові оператори та нові оператори []
Девід Родрігес - dribeas

22

Далі цитата з більш ефективної книги С ++ від Скотта Майєрса:

Новий оператор викликає функцію для виконання необхідного розподілу пам'яті, і ви можете переписати або перевантажити цю функцію, щоб змінити її поведінку. Назва функції, яку новий оператор викликає для виділення пам'яті, - оператор new.


7
Термін, очевидно, придуманий автором книги (або, можливо, запозичений у якогось застарілого джерела). У формальній номенклатурі C ++ немає такого терміна, як "новий оператор".
ANT

2
@AndreyT: Я здійснив пошук C ++ 11 для "нового оператора" і виявив, що він посилається в чотирьох місцях. Зокрема, дві згадки про "нового оператора розміщення"
Mooing Duck,

11

Немає різниці між "новим оператором" та "новим оператором". Обидва посилаються на одне і те ж: функцію, що завантажується / замінюється, operator newяка зазвичай виконує необмежене розподілення пам'яті для об'єктів, створених за допомогою нових виразів .

Зауважимо також, що жоден термін не присутній у мовній специфікації (що є визначальним джерелом офіційної термінології).

Коли ви використовуєте newу своїй програмі для створення об'єкта, він називається new-express . Новий вираз складається з ключового словаnew та додаткових синтаксичних частин, визначених граматикою. Жодна частина синтаксису цього виразу ніколи не називається "оператором".

Функція необмеженої пам'яті operator newофіційно називається просто " operator newфункцією". Зауважте, що слова operatorта newв цій послідовності є лише двома окремими ключовими словами мови C ++. Вони не утворюють англійського терміна "оператор новий". Ніде в специфікаціях мови ви не знайдете посилань на "новий оператор" як англійський термін. Кожен раз це лише комбінація двох незалежних ключових слів, які створюють синтаксис декларації для функції розподілу пам'яті.

Знову ж таки, у резюме: офіційно в C ++ немає таких термінів англійською мовою, як "оператор новий" або "новий оператор". Колишня послідовність присутня в специфікації мови як просто поєднання ключових слів, а не як англійський термін. Останнього взагалі немає.


14
Ви здаєтеся загубленим в якомусь педантичному ментальному мастурбації. Стандарт неясний у плямах, і це одне з них. "Дискусія про нового оператора" має стільки ж сенсу, як і "обговорення плюсового оператора" або "обговорення + оператора".

7

Коли ви створюєте новий об'єкт, пам'ять виділяється за допомогою оператора new, тоді конструктор викликається для ініціалізації пам'яті. Новий оператор робить як розподіл і ініціалізацію, де , як оператор робить новий тільки розподіл.


6

Питання ОП не належним чином сформульоване. Краще поетапно ставитись як "Різниця між" оператором новий "та" новим виразом "?" Примітка "Оператор новий" часто також позначається "оператором нова функція".

І є багато правильних відповідей навколо, нижче моя:

1> 'новий вираз' виклик 'оператор новий', щоб виділити необроблену пам'ять, а потім конструктор викликів

apple * p = new apple(); //new expression

2> "Оператор новий" виділяє лише необроблену пам'ять, не більша різниця, ніж malloc

void* mem = operator new(sizeof(apple)); //just like calling malloc()
apple* p2 = new(mem) apple(1); //call construct here using placement new.

2

Новий оператор : C ++ підтримує динамічний розподіл об'єктів за допомогою нового оператора. Новий оператор виділяє пам'ять для об'єктів з пулу, який називається безкоштовний магазин. Новий оператор називає оператора спеціальної функції новим.

Оператор новий : Якщо запит містить нульові байти зберігання, оператор new повертає вказівник на окремий об'єкт (тобто повторні дзвінки оператору нові повертають різні покажчики). Якщо для запиту на розподіл недостатньо пам'яті, оператор new повертає NULL або кидає виняток. Перший аргумент для оператора new має бути типу size_t (тип, визначений у STDDEF.H), а тип повернення завжди недійсний *.

Ось посилання MSDN для отримання більш детальної інформації:

Нова функція оператора

Новий Оператор


1
Невелике уточнення: оператор, що не розміщує нове, повинен завжди спричиняти невдачу при розподілі (згідно стандарту); і форми розміщення, такі як ::new(std::nothrow), можуть робити будь-які (цей конкретний приклад повертає нульовий покажчик).

1
  1. new - це оператор, а також ключове слово.

    див. [1] У 2.13 та & в 2.12.

  2. new робить дві речі: T * t = new T (arg);

    1) виділити пам'ять для об'єкта: void * ptr = operator new (sizeof (T));

    // оператор новий - це функція (подібно malloc в c), а не оператор. (див. [1] в 3.7.4). Але пункт 7 [2] сказав, що він теж є оператором. На мою думку, різниця між оператором і функцією невелика, і ви можете це бачити, коли згадуєте, що оператор перевантаження реалізується функціями.

    // ми можемо перевантажувати цього оператора / функцію (оператор новий), роблячи те, що ми хочемо саме тут.

    2) ініціалізувати об'єкт у виділеній пам'яті: виклик T :: T (arg) на ptr

    // це може зробити лише компілятор. Ні я, ні ти не можеш.

    // також компілятор буде викликати конструктори об'єктів-членів та конструктор базового класу, якщо T їх має. І ця виклик рекурсивна. Тільки компілятор може це зробити.

  3. Отже, operator new виконує частину місій нових, і лише в цій частині ми можемо щось зробити.

    [1]: ISO / IEC, N3690. http://ww.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3690.pdf

    [2]: Мейерс, Скотт. Ефективний C ++, 3-й.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.