Evet. İki genel seçenek vardır. Biri - genellikle önerilmez - operator=
from the copy yapıcısını açıkça çağırmaktır :
MyClass(const MyClass& other)
{
operator=(other);
}
Bununla operator=
birlikte, eski durum ve kendi kendini atamadan kaynaklanan sorunlar söz konusu olduğunda, bir mal sağlamak bir zorluktur. Ayrıca, tüm üyeler ve üsler, atanacak olsalar bile önce varsayılan olarak başlatılır other
. Bu, tüm üyeler ve üsler için geçerli olmayabilir ve geçerli olduğu yerde bile anlamsal olarak fazlalıktır ve pratik olarak pahalı olabilir.
Giderek daha popüler hale gelen bir çözüm, operator=
kopya yapıcı ve takas yöntemini kullanarak uygulamaktır .
MyClass& operator=(const MyClass& other)
{
MyClass tmp(other);
swap(tmp);
return *this;
}
ya da:
MyClass& operator=(MyClass other)
{
swap(other);
return *this;
}
Bir swap
işlevin yazılması tipik olarak basittir, çünkü sadece dahili elemanların sahipliğini değiştirir ve mevcut durumu temizlemek veya yeni kaynakları tahsis etmek zorunda değildir.
Kopyalama ve takas deyiminin avantajları, otomatik olarak kendi kendine atamanın güvenli olması ve - takas işleminin atılmaması koşuluyla - son derece güvenli olmasıdır.
Son derece istisnai güvenli olmak için, 'elle' yazılmış bir atama operatörü, tipik olarak, atanan kişinin eski kaynaklarını ayırmadan önce yeni kaynakların bir kopyasını tahsis etmek zorundadır, böylece yeni kaynakları tahsis ederken bir istisna meydana gelirse, eski durum yine de geri döndürülebilir. . Tüm bunlar, kopyala ve değiştir ile ücretsiz olarak gelir, ancak genellikle daha karmaşıktır ve bu nedenle sıfırdan yapılması hataya açıktır.
Dikkat edilmesi gereken tek şey, takas yönteminin std::swap
kopya yapıcı ve atama operatörünün kendisini kullanan varsayılan değil, gerçek bir takas olduğundan emin olmaktır .
Tipik olarak üye swap
olarak kullanılır. std::swap
çalışır ve tüm temel türler ve işaretçi türlerinde 'atışsız' garantilidir. Çoğu akıllı işaretçi, atış garantisi ile de değiştirilebilir.