Sık sık RAII ile karşılaştığım bir sorun. Bunun için iyi bir çözüm olup olmadığını merak ediyordum. Standart RAII yarar sınıfı ileRAII ve çıkarılan şablon argümanları
Başlangıç:
class RAIIHelper {
RAIIHelper() {
AcquireAResource();
}
~RAIIHelper() {
ReleaseTheResource();
}
};
Şimdi, çeşitli nedenlerle, ben bir şablon yapmak gerekir.
template <typename T>
class RAIIHelper {
RAIIHelper(T arg) {
AcquireAResource();
}
~RAIIHelper() {
ReleaseTheResource();
}
};
Şimdi bir kullanım site olduğunu düşünün: Diyelim ayrıca yapıcı şablon parametresi türünde bir argüman alır demek
OsomeObj
türeyemez zaman
SomeType
dışarı yazmak zorunda can sıkıcı
void func() {
RAIIHelper<SomeType> helper(someObj);
}
,
template <typename T>
RAIIHelper<T> makeRAIIHelper(T arg) {
return RAIIHelper<T>(arg);
}
Şimdi öylesine gibi kullanabilirsiniz:
yüzden tipini anlamak için bir yardımcı işlev yazmakvoid func() {
auto helper = makeRAIIHelper(someObj);
}
Harika, değil mi? Bir çakışma var: RAIIHelper
'un artık kopyalanabilir veya hareketli olması gerekiyor ve kaynağın serbest bırakıldığı yıkıcı - potansiyel olarak iki kez çağrılabilir: bir kez makeRAIIHelper
tarafından döndürülen geçici için ve bir kez de arama işlevindeki yerel değişken için.
Pratikte, derleyicim RVO'yu gerçekleştirir ve yıkıcı sadece bir kez çağrılır. Ancak, bu garanti edilmez. Bu, RAIIHelper
bir = delete
'd hareket ettiricisini vermeye çalışırsam, kodun artık derlemediği gerçeğinden görülebilir. o taşındı-den geçirildikten sonra ReleaseTheResource()
aramamamı bilmesi
Ben RAIIHelper için ek devlet ekleyebilir, ama bu tür kesinti almak için makeRAIIHelper()
eklemeden önce gereksiz ekstra bir iş.
RAIIHelper
adresine ekstra durum eklemek zorunda kalmadan tür kesintisi alabilmemin bir yolu var mı?
Orada 'unique_ptr' i yeniden keşfediyor gibi bakıyorum, 'SomeType' türünde hiçbir doğal sentinel nesne olmadığından emin misiniz? – Deduplicator
'unique_ptr' kullanabilirsiniz. –
Uygun bir hareket ettiriciyi yazın ve kopya oluşturucuyu devre dışı bırakın. Bu bir sorun olmamalı. –