Różnica między „nowym operatorem” a „nowym operatorem”?

126

Jaka jest różnica między „nowym operatorem” a „nowym operatorem”?

Sandeep
źródło
3
Cześć, czy możesz wyjaśnić pytanie? Wygląda na to, że gdzieś jest literówka.
Dima Malenko
17
Pytanie jest poprawnie sformułowane, patrz odpowiedzi poniżej. Metodą dynamicznego przydzielania pamięci jest użycie newoperatora. Ten operator może być przeciążony. Aby odróżnić operatora domyślnego od wersji przeciążonej, domyślny jest nazywany „nowym operatorem”, a wersja przeciążona - „nowym operatorem”.
Thomas Matthews
2
Jak to zrobić. Jestem nowy i nieświadomy.
Sandeep

Odpowiedzi:

127

Zwykle staram się ująć to w inny sposób, aby nieco lepiej rozróżnić te dwa elementy, ale w każdym razie to dobre pytanie.

Operator new to funkcja alokująca pamięć surową - przynajmniej koncepcyjnie niewiele się od niej różni malloc(). Chociaż jest to dość niezwykłe, chyba że piszesz coś w rodzaju własnego kontenera, możesz bezpośrednio zadzwonić do operatora nowego, na przykład:

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

Możliwe jest również przeciążenie operatora new globalnie lub dla określonej klasy. IIRC, podpis:

void *operator new(size_t);

Oczywiście, jeśli przeciążasz operator new (globalny lub dla klasy), będziesz również chciał / musiał przeciążać również dopasowany operator delete. Co jest warte, istnieje również oddzielny operator new [], który służy do przydzielania pamięci dla tablic - ale prawie na pewno lepiej jest całkowicie zignorować ten cały bałagan.

Nowy operator jest tym, czego zwykle używasz do tworzenia obiektu z darmowego sklepu:

my_class *x = new my_class(0);

Różnica między nimi polega na tym, że operator new po prostu przydziela nieprzetworzoną pamięć, nic więcej. Operator new zaczyna od użycia operatora new do alokacji pamięci, ale następnie wywołuje konstruktor dla odpowiedniego typu obiektu, więc wynikiem jest prawdziwy, żywy obiekt utworzony w tej pamięci. Jeśli ten obiekt zawiera inne obiekty (osadzone lub jako klasy bazowe), te konstruktory również są wywoływane.

Jerry Coffin
źródło
18
+1, co do innego wyrażenia , standard używa dookoła nowego wyrażenia i tylko raz używa nowego operatora do odniesienia się do miejsca wywołania. Zwykle robię to samo: nowy operator dla alokatora i nowe wyrażenie do użycia.
David Rodríguez - drybling
3
Nowe wyrażenie to cała fraza, która zaczyna się od nowego. Jak więc nazywasz tę „nową” część? Jeśli błędne jest wywołanie tego operatora new, to nie powinniśmy wywoływać operatora „sizeof” operatora sizeof lub operatora address-of (gdy zachowuje się jak jeden).
Kaz
1
Kontynuując uwagę Kaza, być może pytanie powinno zostać sformułowane w następujący sposób: Jaka jest różnica między nowym operatorem a nowym operatorem? :)
CS
2
„operator nowy” a „nowe słowo kluczowe”
user997112
2
@antred: Wydałbyś to z czymś w rodzaju operator delete(x);.
Jerry Coffin
35

„nowy operator”

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

„nowy operator”:

Foo* foo = new Foo();

W tym przykładzie new Foo()callFoo::operator new()

Innymi słowy, „dzwoni nowy operator”operator new() ”, podobnie jak w przypadku + operatoraoperator +()

Austin Hyde
źródło
13
newnie jest operatorem w C ++. sizeofNa przykład, operator, ale newi deletenie. newi deletesą słowami kluczowymi i konstrukcjami składni, które tworzą te słowa kluczowe, nazywane są nowe-wyrażenie i usuń-wyrażenie .
AnT
2
Uh, jeśli już, sizeofto konstrukcja składniowa newi deleteoba są poprawnymi, prawnymi i przeciążalnymi operatorami. Ze wszystkiego, co kiedykolwiek widziałem newi deleteobaj są operatorami. Zobacz [cplusplus.com] [ cplusplus.com/doc/tutorial/classes2/]
Austin Hyde,
7
Błędny. Oficjalna terminologia C ++ to terminologia zdefiniowana w specyfikacji języka, a nie w niektórych witrynach internetowych. W specyfikacji języka nie ma takiego słowa jak „nowy operator”, ale jest takie określenie jak „ operator newfunkcja”. Ponownie, sizeofjest osobiĹ określane jako „operator”, natomiast newi deletenigdy dalej operatorów.
AnT
6
AndreyT: Niepoprawnie. Standard C ++ wywołuje operatora „new”, patrz 13.5 / 1.
3
@AndreyT: Tak jak ty, pomyślałem, że operator new był alokatorem, a nowe wyrażenie używał. Przejrzałem i sprawdziłem, że w §5.3.4 / 3 obecny standard używa terminu nowy operator . Później w §5.3.4 / 8 określa funkcje podzielnika jako nowy operator
David Rodríguez - dribeas
22

Oto cytat z książki More Effective C ++ autorstwa Scotta Meyersa:

Nowy operator wywołuje funkcję, aby wykonać wymaganą alokację pamięci, i możesz przepisać lub przeciążać tę funkcję, aby zmienić jej zachowanie. Nazwa funkcji, którą nowy operator wywołuje w celu przydzielenia pamięci, to operator nowy.

Naveen
źródło
7
Termin jest oczywiście wymyślony przez autora książki (a może zapożyczony z jakiegoś przestarzałego źródła). W formalnej nomenklaturze C ++ nie ma takiego terminu jak „nowy operator”.
AnT
2
@AndreyT: Poszukałem w C ++ 11 „nowego operatora” i znalazłem odwołanie w czterech miejscach. Konkretnie, dwa odniesienia do „umieszczania nowego operatora”
Mooing Duck
11

Nie ma różnicy między „nowym operatorem” i „nowym operatorem”. Oba odnoszą się do tego samego: do przeciążalnej / wymiennej operator newfunkcji, która zazwyczaj wykonuje alokację surowej pamięci dla obiektów utworzonych przez nowe wyrażenia .

Należy również zauważyć, że żaden termin nie występuje w specyfikacji języka (która jest definiującym źródłem oficjalnej terminologii).

Kiedy używasz neww swoim programie do tworzenia obiektu, nazywa się to nowym wyrażeniem . Nowe wyrażenie składa się ze słowa kluczowego newi dodatkowych części składniowych zdefiniowanych przez gramatykę. Żadna część składni tego wyrażenia nie jest nigdy nazywana „operatorem”.

Funkcja alokacji pamięci surowej operator newjest oficjalnie nazywana po prostu „ operator newfunkcją”. Zwróć uwagę, że słowa operatoriw newtej kolejności to tylko dwa oddzielne słowa kluczowe języka C ++. Nie tworzą angielskiego terminu „operator nowy”. Nigdzie w specyfikacji języka nie znajdziesz żadnych odniesień do „operator new” jako terminu angielskiego. Za każdym razem jest to po prostu połączenie dwóch niezależnych słów kluczowych, które tworzą składnię deklaracji dla funkcji alokacji pamięci.

Ponownie, w CV: formalnie w C ++ nie ma takich angielskich terminów jak „operator new” czy „new operator”. Pierwsza sekwencja występuje w specyfikacji języka jako zwykła kombinacja słów kluczowych, a nie jako termin angielski. Tej ostatniej w ogóle nie ma.

Mrówka
źródło
14
Wydajesz się zagubiony w pedantycznej mentalnej masturbacji. Norma jest miejscami niejasna, a to jest jeden z nich. „Omawianie nowego operatora” ma tak samo sens, jak „omawianie operatora plus” lub „omawianie operatora +”.
7

Podczas tworzenia nowego obiektu pamięć jest przydzielana za pomocą operatora new, a następnie wywoływany jest konstruktor w celu zainicjowania pamięci. Nowy operator ma zarówno alokacji i inicjalizacji, gdzie jako operator robi tylko nowy przydział.

Chris Fulstow
źródło
6

Pytanie PO nie zostało poprawnie sformułowane. Lepiej jest fazować jako „Różnica między„ nowym operatorem ”a„ nowym wyrażeniem ”? Uwaga „nowy operator” często odnosi się również do „nowej funkcji operatora”.

Wokół jest mnóstwo poprawnych odpowiedzi, poniżej moja:

1> 'nowe wyrażenie' wywołaj 'operator new', aby przydzielić pamięć surową, a następnie wywołaj konstruktor

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

2> 'operator new' alokuje tylko surową pamięć, niewiele różni się od malloc

void* mem = operator new(sizeof(apple)); //just like calling malloc()
apple* p2 = new(mem) apple(1); //call construct here using placement new.
Gob00st
źródło
2

Nowy operator : C ++ obsługuje dynamiczne przydzielanie obiektów przy użyciu nowego operatora. Nowy operator przydziela pamięć dla obiektów z puli zwanej wolnym magazynem. Nowy operator nazywa operatora funkcji specjalnej nowym.

operator new : Jeśli żądanie dotyczy zerowych bajtów pamięci, operator new zwraca wskaźnik do odrębnego obiektu (to znaczy, powtarzające się wywołania operatora new zwracają różne wskaźniki). Jeśli nie ma wystarczającej ilości pamięci dla żądania alokacji, operator new zwraca NULL lub zgłasza wyjątek. Pierwszy argument operatora new musi być typu size_t (typ zdefiniowany w STDDEF.H), a typem zwracanym jest zawsze void *.

Oto linki MSDN, aby uzyskać więcej informacji:

Operator nowa funkcja

Nowy operator

aJ.
źródło
1
Nieznaczne wyjaśnienie: nowy operator, który nie jest umiejscowiony, musi zawsze zgłosić błąd przydziału (zgodnie ze standardem); i formularze umieszczania, takie jak::new(std::nothrow) , mogą to zrobić (ten konkretny przykład zwraca wskaźnik pusty).
1
  1. new to zarówno operator, jak i słowo kluczowe.

    patrz [1] w 2.13 i & w 2.12.

  2. new robi dwie rzeczy: T * t = new T (arg);

    1) przydziel pamięć dla obiektu: void * ptr = operator new (sizeof (T));

    // operator new jest funkcją (podobnie jak malloc w c), a nie operatorem (patrz [1] w 3.7.4). Ale pozycja 7 [2] mówi, że jest to również operator. Moim zdaniem różnica między operatorem a funkcją jest niewielka i widać to, gdy przypomnimy sobie, że operator przeciążania jest realizowany przez funkcje.

    // możemy przeciążyć ten operator / funkcję (operator new) robiąc to, co chcemy właśnie tutaj.

    2) zainicjuj obiekt w przydzielonej pamięci: wywołaj T :: T (arg) na ptr

    // tylko kompilator może to zrobić. Ani ja, ani ty nie możesz.

    // także kompilator wywoła konstruktory obiektów składowych i konstruktor klasy bazowej, jeśli T je posiada. A to wezwanie jest rekurencyjne. Tylko kompilator może to zrobić.

  3. Tak więc operator new wykonuje część misji nowych i tylko w tej części możemy coś zrobić.

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

    [2]: Meyers, Scott. Efektywne C ++, 3rd.

njuhgn
źródło