Yazılım geliştirmede deyimler: Copy and swap deyimi

Adanali

Active member
Yazılım geliştirmede deyimler: Copy and swap deyimi


  1. Yazılım geliştirmede deyimler: Copy and swap deyimi

Dil, bir mimari veya tasarım modelinin belirli bir programlama dilinde uygulanmasıdır. Uygulamanız bir programlama dili için deyimsel. Bugün C++’ta güçlü istisna güvenlik garantisi sunan kopyala ve takas deyimini tanıtacağım.







Rainer Grimm, uzun yıllardır yazılım mimarı, ekip lideri ve eğitim yöneticisi olarak çalışmaktadır. C++, Python ve Haskell programlama dilleri üzerine makaleler yazmaktan hoşlanır, aynı zamanda sık sık uzmanlık konferanslarında konuşmaktan da keyif alır. Modernes C++ blogunda yoğun bir şekilde C++ tutkusundan bahsediyor.













Kopyala ve değiştir deyimi hakkında yazmadan önce, istisna garantisine açıklık getirmeliyim. İşte bazı genel sorun giderme konuları:

Hata yönetimi


Hata işleme, iyi bir yazılımın önemli bir parçasıdır. Bu nedenle, C++ Çekirdek Yönergeleri, hata işleme için yaklaşık 30 kural sunar.Yönergelere göre, hata işlemenin hangi yönleri vardır?

  • Bir hatanın tespiti
  • Bir hatayla ilgili bilgilerin bir yönetici koduna iletilmesi
  • Bir programın durumunu geçerli bir durumda tutun
  • Kaynak kayıplarından kaçının
Hata işleme için istisnalar kullanmalısınız. Boost kitaplığının kurucularından biri ve ISO C++ standardizasyon komitesinin eski bir üyesi olan David Abrahams, “Genel Bileşenlerde İstisna Güvenliği” belgesinde istisna güvenliğinin anlamını resmileştiriyor.


İbrahim’in garantileri

Abrahams Garantileri, istisnaların güvenliği için temel bir sözleşmeyi tanımlar. İşte sözleşmenin dört seviyesi:

  1. Atış garantisi yok, f olarak da adlandırılıryardım şeffaflığı: İstisnai durumlarda bile operasyonların başarılı olması ve tüm ihtiyaçları karşılaması garanti edilir. Bir istisna meydana gelirse, dahili olarak işlenir ve müşteriler tarafından gözlemlenmez.
  2. Güçlü istisna güvenliğitaahhüt olarak da bilinir veya geri alma semantiği: İşlemler başarısız olabilir, ancak başarısız işlemlerin hiçbir yan etkisi olmayacağı garanti edilir, böylece tüm veriler orijinal değerlerini korur.
  3. Temel istisna güvenliğiolarak da bilinir kayıp garantisi yok: Başarısız işlemlerin kısmen yürütülmesi yan etkilere neden olabilir, ancak tüm değişmezler korunur ve kaynak sızıntısı olmaz (bellek sızıntıları dahil). Arşivlenen tüm veriler, istisnadan önceki durumlarından farklı olsalar bile geçerli değerler içerecektir.
  4. Güvenlik istisnası yok: Herhangi bir garanti verilmemektedir.
Genel olarak, en azından temel istisna güvenlik garantisini (3) uygulamanız gerekir. Bu, bir hata durumunda hiçbir kaynağın kaybolmadığı ve programın her zaman iyi tanımlanmış bir durumda olduğu anlamına gelir. Bir hatadan sonra program iyi tanımlanmış bir durumda değilse, tek bir seçenek vardır: programdan çıkmak.

Kopyala ve değiştir deyimi, güçlü istisnalar için bir güvenlik garantisi sağlar (2). Bu, temel istisnalar için güvenlik garantisinden daha güçlü bir garantidir (3).

Dil kopyaları ve değişimleri


takas fonksiyonu

Bir türün normal bir tür olması için bir değişim işlevini desteklemesi gerekir. Normal bir türün daha resmi olmayan bir tanımı, bir tür gibi davranan bir türdür. int davranır. Bir sonraki yazılardan birinde düzenli tipler hakkında yazacağım. C++ Çekirdek Yönergelerinin “C.83: Değer benzeri türler için, noexcept takas işlevi sağlamayı düşünün” ve “C.85: Swap noexcept yap” kurallarına göre, bir takas işlevi başarısız olmamalı ve noexcept yapı. Aşağıdaki veri türü Foo değiştirme işlevi vardır.


class Foo {
public:
void swap(Foo& rhs) noexcept {
m1.swap(rhs.m1);
std::swap(m2, rhs.m2);
}
private:
Bar m1;
int m2;
};


Kolaylık sağlamak için, önceden uygulanan exchange üye işlevine dayalı olarak üye olmayan bir exchange işlevini desteklemeyi düşünün.


void swap(Foo& a, Foo& b) noexcept {
a.swap(b);
}


Bir takas işlevi sağlamazsanız, takas gerektiren standart kitaplık algoritmaları (örn. std::sort Ve std::rotate), üzerinde std::swapMove semantiğine dayalı olarak uygulanan şablon.


template<typename T>
void std::swap(T& a, T& b) noexcept {
T tmp(std::move(a));
a = std::move(b);
b = std::move(tmp);
}


C++ standardı, 40’tan fazla aşırı yükleme sağlar. std::swap. an Takas işlevini birçok deyim için bir yapı taşı olarak kullanabilirsiniz, örn. B. kopya oluşturma veya hareket ataması için. Bu da beni kopyala ve değiştir deyimine getiriyor.

Kopyala ve değiştir

Copy and move yapıcısını uygulamak için copy and swap deyimi kullanılıyorsa, takas işlevi bir üye işlev veya arkadaş işlevi olarak tanımlanmalıdır. dersim var Cont bir takas işlevi ekledi ve bunu kopyala ve taşı atamasında kullan.


class Cont {
public:
// ...
Cont& operator = (const Cont& rhs);
Cont& operator = (Cont&& rhs) noexcept;
friend void swap(Cont& lhs, Cont& rhs) noexcept {
swap(lhs.size, rhs.size);
swap(lhs.pdata, rhs.pdata);
}
private:
int* pData;
std::size_t size;
};

Cont& Cont::eek:perator = (const Cont& rhs) {
Cont tmp(rhs); // (1)
swap(*this, tmp); // (3)
return *this;
}

Cont& Cont::eek:perator = (Cont&& rhs) {
Cont tmp(std::move(rhs)); // (2)
swap(*this, tmp); // (3)
return *this;
}


Her iki atama işleci de geçici bir kopya oluşturur tmp kaynak nesnenin (1 ve 2) ve ardından swap-Üzerlerinde fonksiyon (3 ve 4). Eğer kullanılan swap-fonksiyonlar noexcept , atama operatörünün kopyalanması ve atama operatörünün taşınması, güçlü istisna güvenlik garantisini destekler. Bu, her iki atama işlecinin de işlem çağrısının bir hata durumunda, sanki hata hiç olmamış gibi tamamen geri alınacağını garanti ettiği anlamına gelir.

Kopyala ve değiştir deyimini destekleyen işlemler, işleme dayalı bir tarzda programlamaya izin verir. Bir operasyon hazırlarsınız (kopya üzerinde çalışırsınız) ve işler iyi gittiğinde operasyonu yayınlarsınız (sonucu değiştirirsiniz). Copy and swap deyimi oldukça popüler olan çok güçlü bir deyimdir.

yarışma: Değişiklik yerel bir nesnede gerçekleşir. Veriler paylaşılmadığından, tanım gereği bu iş parçacığı güvenlidir. Değişiklik tamamlandığında, paylaşılan verilerin üzerine güvenli bir şekilde yerel veriler yazılır.

sürüm kontrol sistemi: Önce verileri kontrol edip yerel bir kopya alırsınız. Değişiklikler hazır olduğunda tekrar yayınlanacaktır. Bir birleştirme çakışmasını çözmeniz gerekebilir. Birleştirme çakışmasını çözemezseniz geçersiz kılmayı atın ve tekrar kontrol edin.

Bir takas işlevi, hareket anlambilimi yerine kopya anlambilime dayanıyorsa, takas işlevi bellek yetersizliğinden dolayı başarısız olabilir. Aşağıdaki uygulama, “C++94: A swap function must not fail” C++ Çekirdek Yönergeleri kuralını ihlal ediyor: Bu, C++98 uygulamasının std::swap.


template<typename T>
void std::swap(T& a, T& b) {
T tmp = a;
a = b;
b = tmp;
}


Bu durumda, bellek yönetimi std::bad_alloc– istisna nedeniyle.

Sıradaki ne?


Kısmi işlev uygulaması, bir işlevin bazı bağımsız değişkenlerini bağladığı ve daha az bağımsız değişkenli bir işlev döndürdüğü bir tekniktir. Bu teknik, işlevsel dillerde sıklıkla kullanılan köri ile ilgilidir.

Benim küçük Noel tatilim

Önümüzdeki iki hafta boyunca blogda bir makale yayınlamayacağım. Bu nedenle bir sonraki makalem 9 Ocak’ta yayınlanacak. Sessiz ve düşünceli bir an.


(rm)



ana sayfaya
 
Üst