"Yeni operatör" ve "yeni operatör" arasındaki fark nedir?


126

"Yeni operatör" ve "yeni operatör" arasındaki fark nedir?


3
Merhaba, lütfen soruyu netleştirir misiniz? Görünüşe göre bir yerde yazım hatası var.
Dima Malenko

17
Soru doğru ifade edilmiştir, aşağıdaki cevaplara bakın. Dinamik olarak bellek ayırma yöntemi, newoperatörü kullanmaktır . Bu operatör aşırı yüklenebilir. Varsayılan operatör ile aşırı yüklenmiş sürümü birbirinden ayırt etmek için, varsayılan "yeni operatör" ve aşırı yüklenmiş sürüm "operatör yeni" olarak adlandırılır.
Thomas Matthews

2
Bu nasıl yapılır. Ben yeniyim ve farkında değilim.
Sandeep

Yanıtlar:


127

Genelde ikisini biraz daha iyi ayırt etmek için her şeyi farklı bir şekilde ifade etmeye çalışırım, ancak bu her durumda iyi bir soru.

Yeni operatör, ham belleği ayıran bir işlevdir - en azından kavramsal olarak, bundan çok da farklı değildir malloc(). Kendi konteynırınız gibi bir şey yazmadığınız sürece oldukça sıra dışı olsa da, operatörü aşağıdaki gibi doğrudan yeni arayabilirsiniz:

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

Operatörün yeni global olarak veya belirli bir sınıf için aşırı yüklenmesi de mümkündür. IIRC, imza:

void *operator new(size_t);

Elbette, yeni bir operatörü aşırı yüklerseniz (global veya bir sınıf için), aynı zamanda eşleşen operatör silme işlemine de aşırı yükleme isteyeceksiniz / ihtiyacınız olacaktır. Değeri ne olursa olsun, diziler için bellek ayırmak için kullanılan ayrı bir operatör new [] de vardır - ancak bu karışıklığı tamamen görmezden gelmeniz neredeyse kesinlikle daha iyidir.

Yeni operatör, normalde ücretsiz mağazadan bir nesne oluşturmak için kullandığınız şeydir:

my_class *x = new my_class(0);

İkisi arasındaki fark, new operatörünün sadece ham belleği ayırmasıdır, başka hiçbir şey. Yeni operatör, bellek ayırmak için new operatörünü kullanarak başlar, ancak daha sonra doğru nesne türü için yapıcıyı çağırır, böylece sonuç, o bellekte oluşturulan gerçek bir canlı nesnedir. Bu nesne başka nesneler içeriyorsa (gömülü veya temel sınıflar olarak), bu yapıcılar da çağrılır.


18
+1, farklı bir ifadeyle ilgili olarak , standart her yerde yeni bir ifade kullanır ve yalnızca bir kez arama yerine atıfta bulunmak için yeni operatör kullanır . : Ben aynı şeyi eğilimindedir yeni operatörünü için ayırıcı ve yeni anlatım kullanım için.
David Rodríguez - dribeas

3
Yeni bir ifade, yeni ile başlayan tüm ifadedir. Öyleyse, sadece "yeni" kısmına ne diyorsunuz? Bunu yeni operatör olarak adlandırmak yanlışsa, o zaman sizeof operatörü "sizeof" u veya operatörün adresini (tek gibi davrandığında) çağırmamalıyız.
Kaz

1
Kaz'ın açıklamasını takiben, belki de soru şu şekilde yeniden ifade edilmelidir: Yeni operatör ile operatör yeni operatör arasındaki fark nedir? :)
CS

2
"operatör yeni" ve "yeni anahtar kelime"
user997112

2
@antred: Bunu gibi bir şeyle yayınlarsınız operator delete(x);.
Jerry Coffin

35

"operatör yeni"

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

"yeni operatör":

Foo* foo = new Foo();

Bu örnekte new Foo()aramalarFoo::operator new()

Başka bir deyişle, operator new()+ operatör çağrıları gibi "yeni operatör" arar " "operator +()


13
newC ++ 'da bir operatör değildir. sizeofÖrneğin bir operatör, ancak newve deletedeğildir. newve deletebu anahtar kelimelerin oluşturduğu sözdizimsel yapılar ve yeni ifade ve silme ifadesi olarak adlandırılır .
AnT

2
Uh, eğer bir şey varsa sizeof, sözdizimsel yapıdır newve deleteher ikisi de geçerli, yasal, aşırı yüklenebilir operatörler. Gördüğüm her şeyden newve deleteikisi de operatör. Bkz. [Cplusplus.com] [ cplusplus.com/doc/tutorial/classes2/]
Austin Hyde

7
Yanlış. Resmi C ++ terminolojisi, bazı web siteleri tarafından değil, dil spesifikasyonu tarafından tanımlanan terminolojidir. Dil spesifikasyonunda "yeni operatör" diye bir term yoktur, ancak " operator newişlev" diye bir terim vardır . Yine sizeofiken explicilty, bir "operatör" olarak adlandırılır newve deleteedilmektedir asla operatörler olarak anılacaktır.
AnT

6
AndreyT: Yanlış. C ++ standardı 'yeni' bir operatör çağırır, bkz. 13.5 / 1.

3
@AndreyT: Senin gibi, düşündük operatör yeni oldu ayırıcısı ve yeni ifade kullanır. §5.3.4 / 3'te mevcut standardın yeni operatör terimini kullandığını inceledim ve kontrol ettim . Daha sonra §5.3.4 / 8'de ayırıcı işlevlerini yeni operatör
David Rodríguez - dribeas

22

Aşağıda Scott Meyers'in More Effective C ++ kitabından alıntı:

Yeni operatör, gerekli bellek tahsisini gerçekleştirmek için bir işlevi çağırır ve davranışını değiştirmek için bu işlevi yeniden yazabilir veya aşırı yükleyebilirsiniz. Yeni operatörün bellek ayırmak için çağırdığı işlevin adı yeni operatördür.


7
Bu terim açıkça kitabın yazarı tarafından icat edilmiştir (veya belki de eski bir kaynaktan ödünç alınmıştır). Resmi C ++ terminolojisinde "yeni operatör" diye bir terim yoktur.
AnT

2
@AndreyT: "Yeni operatör" için C ++ 11'i aradım ve dört yerde başvurulduğunu buldum. Spesifik olarak, "yeni yerleştirme operatörü" için iki referans
Mooing Duck

11

"Yeni operatör" ve "yeni operatör" arasında hiçbir fark yoktur. Her ikisi de aynı şeyi ifade ederoperator new : yeni ifadeler tarafından oluşturulan nesneler için tipik olarak ham bellek tahsisi gerçekleştiren aşırı yüklenebilir / değiştirilebilir işlev .

Dil spesifikasyonunda (resmi terminolojinin tanımlayıcı kaynağı olan) hiçbir terimin bulunmadığına da dikkat edin.

newProgramınızda bir nesne oluşturmak için kullandığınızda buna yeni ifade denir . Yeni ifade , anahtar sözcük newve dilbilgisi tarafından tanımlanan ek sözdizimsel bölümlerden oluşur . Bu ifadenin sözdiziminin hiçbir parçası hiçbir zaman "operatör" olarak adlandırılmaz.

Ham bellek ayırma işlevi operator newresmi olarak sadece " operator newişlev" olarak adlandırılır . Not kelime olduğunu operatorve newbu dizide sadece iki ayrı C ++ dilinin anahtar kelimelerdir. İngilizce bir "operatör yeni" terimi oluşturmazlar. Dil spesifikasyonunun hiçbir yerinde "yeni operatör" için İngilizce bir terim olarak referans bulamazsınız. Her seferinde bu, bir bellek ayırma işlevi için bildirim sözdizimi üreten iki bağımsız anahtar sözcüğün yalnızca bir kombinasyonudur.

Yine, özgeçmişte: resmi olarak C ++ 'da "yeni operatör" veya "yeni operatör" gibi İngilizce terimleri yoktur. İlk sıra, dil spesifikasyonunda İngilizce bir terim olarak değil, yalnızca anahtar kelimelerin bir kombinasyonu olarak mevcuttur. İkincisi hiç mevcut değil.


14
Bilgiççe bir zihinsel mastürbasyonda kaybolmuş gibisin. Standart noktalar konusunda belirsizdir ve bu onlardan biridir. "Artı işlecini tartışmak" veya "+ işlecini tartışmak" kadar "yeni işleci tartışmak" da aynı derecede mantıklıdır.

7

Yeni bir nesne oluşturduğunuzda, bellek new operatörü kullanılarak ayrılır ve ardından yapıcı, belleği başlatmak için çağrılır . Yeni operatör tahsisi ve operatör yeni tek tahsisi yaptığı gibi başlatmayı, hem yok.


6

OP'nin sorusu doğru bir şekilde ifade edilmemiştir. "Yeni operatör" ve "yeni ifade" arasındaki fark olarak aşamalı hale getirmek daha iyidir. Not 'operatör yeni' genellikle 'operatör yeni işlevi' anlamına da gelir.

Ve etrafta pek çok doğru cevap var, aşağıda benimki:

1> 'yeni ifade' ham belleği ayırmak için 'yeni' operatörü çağırın, ardından kurucuyu çağırın

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

2> 'operatör yeni' sadece ham belleği ayırır, malloc'tan çok fark yoktur

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

2

Yeni operatör : C ++, yeni operatörü kullanarak nesnelerin dinamik olarak tahsis edilmesini destekler. Yeni operatör, boş depo adı verilen bir havuzdan nesneler için bellek ayırır. Yeni operatör, özel fonksiyon operatörünü yeni olarak çağırır.

operatör yeni : İstek sıfır bayt depolama içinse, yeni işleci farklı bir nesneye bir işaretçi döndürür (yani, yeni işleci için tekrarlanan çağrılar farklı işaretçiler döndürür). Tahsisat talebi için yetersiz bellek varsa, new operatörü NULL döndürür veya bir istisna atar. New operatörünün ilk bağımsız değişkeni size_t (STDDEF.H'de tanımlanan bir tür) türünde olmalıdır ve dönüş türü her zaman void * olmalıdır.

Daha fazla ayrıntı için bir MSDN bağlantısı:

Operatörün Yeni Fonksiyonu

Yeni Operatör


1
Hafif açıklama: yeni yerleştirme dışı operatör her zaman tahsis hatası atmalıdır (standarda göre); ve gibi yerleştirme formları ::new(std::nothrow)her ikisini de yapabilir (bu belirli örnek bir boş gösterici döndürür).

1
  1. new , bir operatörün yanı sıra bir anahtar kelimedir.

    bkz. [1] 2.13 ve && 2.12.

  2. new iki şey yapar: T * t = new T (arg);

    1) nesne için bellek ayırın: void * ptr = yeni operatör (sizeof (T));

    // yeni operatör bir operatör değil , bir işlevdir (c'deki malloc gibi) (bkz. [1] 3.7.4'te). Ancak Madde 7 [2] bunun da bir operatör olduğunu söyledi. Bana göre, operatör ve fonksiyon arasındaki fark küçüktür ve aşırı yükleme operatörünün fonksiyonlar tarafından uygulandığını hatırladığınızda bunu görebilirsiniz.

    // bu operatörü / fonksiyonu (operatör yeni) burada istediğimizi yaparak aşırı yükleyebiliriz.

    2) tahsis edilen bellekteki nesneyi başlat: ptr'de T :: T (arg) çağır

    // bunu yalnızca derleyici yapabilir. Ne ben ne de sen yapabilirsin.

    // Ayrıca derleyici, üye nesnelerin yapıcılarını ve T'ye sahipse temel sınıfın yapıcısını çağırır. Ve bu çağrı yinelemelidir. Bunu yalnızca derleyici yapabilir.

  3. Yani, operatör yeni, yeninin görevlerinin bir bölümünü yapıyor ve sadece bu bölümde bir şeyler yapabiliriz.

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

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.