operatör ((), varsayılan kurucunun varlığına bağlı olarak operatör silme () silindiğinde farklı davranır


17

New () operatörü ile C sınıfı yeni bir nesne oluşturmak burada bir hata verir:

class C
{
public:
    C() {}
    virtual ~C() {}

    void operator delete(void*) = delete;
};


int main()
{
    C* c = new C;
}

ile C2280: 'void C::operator delete(void *)': function was explicitly deleted

Ancak , derleyici C() {} ile değiştirdiğimde C() = default;veya kaldırdığımda, derleyici varsayılan bir yapıcı eklediğinde (ki aynı etkiye sahip olduğuna inanıyorum = default), kod derlenecek ve çalışacaktır.

Derleyici tarafından oluşturulan varsayılan kurucu ile bunu yapan kullanıcı tanımlı varsayılan kurucu arasındaki farklar nelerdir?

Ben bazı ipucu var bu gönderme , ama burada sınıf C yoketme, sağ sanal olduğundan önemsiz değil (kullanıcı tarafından sağlanan yapıcı olmadan)?

En son Visual Studio, c ++ 17 ile derlenmiştir.


3
Emin değilim, ama farkın varsayılan yapıcı olmasınoexcept
Sebastian Redl

1
G ++ ile çoğaltılamaz. Kurucunun operator delete()el ile yazılması veya örtük olarak üretilmesi ile ilgili benzer teşhis . Bu benim beklentilerimle tutarlı - newifade tarafından bir istisna atılabileceğinden , derleyicinin erişmesi gerekiyor operator delete().
Peter

@SebastianRedl haklısın, ekleme noexceptkod derleme yapacak, ama nasıl ...?
yeshjho

1
@Peter İstisna sadece kurucu tarafından atılabilir, bu nedenle noexceptSebastianRedl'in belirttiği gibi ise , bir çağrı operator deletedahil edilmesine gerek yoktur. Ayrıca g ++ sadece yıkıcı sanal ise şikayetçi olur. Aksi halde, yapıcı fırlatsa bile her zaman derler.
ceviz

@LeDYoM Bağlantınız, soruyla alakasız görünen IP adreslerini ayrıştırmakla ilgilidir. Yanlış bir bağlantı mı gönderdiniz?
LF

Yanıtlar:


17

Derleyici tarafından oluşturulan varsayılan kurucu ile bunu yapan kullanıcı tanımlı varsayılan kurucu arasındaki farklar nelerdir?

newifadesi ilgili öğeyi çağırır operator newve sonra yapıcıyı çağırır . Yapıcı bir istisna newifadesi atarsa operator new, karşılık gelen çağırarak (bellek sızmasını önlemek için) etkisini geri almak gerekir operator delete. İkincisi silinirse newifade derleyiciyle sonuçlanan ifadeyi çağıramaz error: use of deleted function 'static void C::operator delete(void*)'.

Bir noexceptkurucu muhtemelen bir istisna atamaz, bu nedenle, operator deletebir newifade tarafından çağrılmayacağından karşılık gelen gerekli değildir . Bir defaultönemsiz bir sınıfın yapıcı da olduğu noexceptyapıcı. operator deleteÖzel bir skaler silici yıkıcı ( deletetemel sınıf işaretçisi aracılığıyla ifadeyi etkinleştirmek için bir uygulama detayı ) çağırdığı için sanal bir yıkıcının varlığı silinmemelidir operator delete.

C ++ standardı tarafından, derleyicinin ifade operator deleteile çağrılmasa bile silinmemesi gerekip gerekmediği belirtilmemiş gibi görünüyor new. gccAncak gelen yürütmesini görünmüyor operator deleteiçinde newÇünkü eğer hiç ifade deleted (a yayınlanmıştır hata raporu ).

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.