Varsayılan / kopyala / taşı ve atama operatörünü kopyala / taşı operatörünün otomatik olarak oluşturulması için koşullar?


Yanıtlar:


136

Aşağıda, "otomatik olarak oluşturulmuş", "dolaylı olarak varsayılan olarak ilan edildi, ancak silinmiş olarak tanımlanmadı" anlamına gelir. Özel üye işlevlerinin bildirildiği ancak silinmiş olarak tanımlandığı durumlar vardır.

  • Varsayılan kurucu, kullanıcı tanımlı bir kurucu yoksa otomatik olarak oluşturulur (§12.1 / 5).
  • Kopya yapıcısı, kullanıcı tarafından bildirilen taşıma yapıcısı veya taşıma atama operatörü yoksa otomatik olarak oluşturulur (çünkü C ++ 03'te taşıma oluşturucular veya taşıma atama işleçleri olmadığından, bu, C ++ 03'te "her zaman" olarak basitleştirilir) ( §12.8 / 8).
  • Kopya atama operatörü, kullanıcı tarafından beyan edilen taşıma yapıcısı veya taşıma atama operatörü yoksa otomatik olarak oluşturulur (§12.8 / 19).
  • Yıkıcı, kullanıcı tarafından beyan edilen bir yıkıcı yoksa otomatik olarak oluşturulur (§12.4 / 4).

Yalnızca C ++ 11 ve sonrası:

  • Taşıma yapıcısı, kullanıcı tarafından bildirilen kopya oluşturucu, kopya atama operatörü veya yıkıcı yoksa ve üretilen taşıma oluşturucu geçerliyse otomatik olarak oluşturulur (§12.8 / 10).
  • Taşıma atama operatörü, kullanıcı tarafından beyan edilen kopya oluşturucu, kopya atama operatörü veya yıkıcı yoksa ve oluşturulan taşıma atama operatörü geçerliyse (örn. Sabit üyeler ataması gerekmiyorsa) otomatik olarak oluşturulur (§12.8 / 21).

9
Kalıtsal bir yıkıcı sayılır mı? Demek istediğim, boş bir sanal yıkıcıya sahip bir temel sınıfım olduğunu varsayalım. Alt sınıflarda hareket oluşturucuların oluşmasını engelliyor mu? Cevap evet ise, temel sınıfta bir hareket oluşturucu tanımlamam yardımcı olur mu?
kamilk

10
Sanırım constsınıftaki üyelere sahip olmanın
anlamsız

"Özel üye işlevlerinin bildirildiği ancak silinmiş olarak tanımlandığı durumlar vardır." Örneğin, sabit veya referans üyelerinizin olduğu, taşınmanın imkansız olduğu yerlere bakın. Hayır, bu olamaz, çünkü orada bir kopya uygulanacak.
towi

Bu forumda köprü göndermenin kısıtlı olduğunu biliyorum. Ama aynı zamanda iyi bir makale - cplusplus.com/articles/y8hv0pDG
bruziuz

Standarttan itibaren örtük olarak varsayılan bir kopya oluşturucunun " sınıfın kullanıcı tarafından bildirilen bir kopya atama operatörü veya kullanıcı tarafından bildirilen bir yıkıcıya sahip olması durumunda kullanımdan kaldırıldığına " dikkat edin ( 12.8 Sınıf nesnelerini kopyalama ve taşıma [class.copy] ).
sigy

98

Aşağıdaki diyagramı çok faydalı buldum.

Otomatik oluşturucular ve atama işleçleri için C ++ kuralları dan Yapışkan Uçları - Sıfır Hero Kural Becoming


Güzel. "Bağımsız" neyi ifade eder? Neyden bağımsız?
towi

8
Kopyalama ctor / atama birbirinden 'bağımsızdır'. Yalnızca birini yazarsanız, derleyici diğerini sağlar. Bunun aksine, bir hareket ctoru veya bir taşıma ataması sağlarsanız, derleyici diğerini sağlamaz.
Marco M.

Kopyalama işlemlerinin bağımsız olmasının sebebinin ne olduğunu merak ediyorum. Tarihi nedenler olabilir? ya da kopyanın hedefini değiştirmeyeceği ama hareket etmediği gerçeği?
RaGa__M

@Explorer_N Evet, geriye dönük uyumluluk, bu nedenle tarihi nedenler. Uzun zaman önce kötü bir tasarım seçimiydi, bu yüzden artık bulunması zor hataları önlemek için "üçün kuralı" (3 veya hiçbirini tanımlayın: kopya oluşturucu, kopya atama operatörü ve genellikle yıkıcı) gibi iyi uygulamalara ihtiyaç var.
atablash

@MarcoM., Anladığım kadarıyla, "Eğer yazarsan ..." koşulu, özel üye işlevinin = delete(açık) veya = default(benim için daha az belirgin ) olarak ayarlanmasının iki durumunu içerir . Haklı mıyım
Enrico Maria De Angelis

2

C ++ 17 N4659 standart taslağı

Hızlı bir çapraz standart referans için, aşağıdaki cppreference girişlerinin "Örtük olarak bildirilmiş" bölümlerine bakın:

Aynı bilgiler elbette standarttan da elde edilebilir. Örneğin, C ++ 17 N4659 standart taslağında :

15.8.1 "Oluşturucuları kopyala / taşı", kopya oluşturucu için şunu söylüyor:

6 Sınıf tanımı bir kopya oluşturucuyu açıkça bildirmezse, açık olmayan bir tanım örtük olarak bildirilir. Sınıf tanımı bir taşıma yapıcısı veya taşıma atama operatörü bildirirse, örtük olarak bildirilen kopya yapıcısı silinmiş olarak tanımlanır; aksi takdirde temerrüde düşmüş olarak tanımlanır (11.4). Sınıfın kullanıcı tarafından bildirilen bir kopya atama operatörü veya kullanıcı tarafından bildirilen bir yıkıcı varsa, ikinci durum kullanımdan kaldırılır.

ve hareket oluşturucu için:

8 Bir X sınıfının tanımı açıkça bir hareket yapıcısı bildirmiyorsa, açık olmayan bir tanım, ancak ve ancak

  • (8.1) - X, kullanıcı tarafından beyan edilen bir kopya oluşturucusuna sahip değil,

  • (8.2) - X'in kullanıcı tarafından beyan edilen kopya atama operatörünün olmaması,

  • (8.3) - X, kullanıcı tanımlı bir hareket atama operatörüne sahip değildir ve

  • (8.4) - X'in kullanıcı tarafından beyan edilen bir yıkıcısı yoktur.

15.8.2 "Atama işleci kopyala / taşı", kopyalama ataması için diyor:

2 Sınıf tanımı bir kopya atama işlecini açık bir şekilde bildirmezse, biri örtük olarak bildirilir. Sınıf tanımı bir taşıma yapıcısı veya taşıma atama operatörü bildirirse, örtük olarak bildirilen kopya atama operatörü silinmiş olarak tanımlanır; aksi takdirde temerrüde düşmüş olarak tanımlanır (11.4). Sınıfın kullanıcı tarafından bildirilen bir kopya yapıcısı veya kullanıcı tarafından bildirilen bir yıkıcıya sahip olması durumunda, ikinci durum kullanımdan kaldırılır.

ve taşıma ataması için:

4 Bir X sınıfının tanımı açıkça bir hareket atama operatörü bildirmiyorsa, biri örtülü olarak varsayılan olarak ilan edilecektir, ancak ve ancak

  • (4.1) - X, kullanıcı tarafından beyan edilen bir kopya oluşturucusuna sahip değil,
  • (4.2) - X, kullanıcı tanımlı bir hareket yapıcısına sahip değil,
  • (4.3) - X, kullanıcı tarafından beyan edilen bir kopya atama operatörüne sahip değildir ve
  • (4.4) - X'in kullanıcı tanımlı bir yıkıcısı yoktur.

15.4 "Destructors", yıkıcılar için şunu söylüyor:

4 Bir sınıfın kullanıcı tanımlı bir yıkıcısı yoksa, bir yıkıcı örtük olarak varsayılan olarak bildirilir (11.4). Örtük olarak bildirilmiş bir yıkıcı, sınıfının bir satır içi public üyesidir.

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.