SORU
3 NİSAN 2009, Cuma


Bu terimin anlamını anlama ve kavram - DEMİRYOLU (Kaynak elde etme Başlatma)

C geliştiricileri bize DEMİRYOLU önemlidir, PEKİ ya diğer diller için herhangi bir alaka olabilir olup olmadığını iyi bir açıklama verebilir misiniz?

Benyapınbiraz biliyorum. Açılımı inanıyorum "Kaynak Satın alma Başlatma". Ancak, bu isim yok jive ile benim (muhtemelen yanlış) bir anlayış ne DEMİRYOLU: benim edindiğim izlenim bu DEMİRYOLU bir şekilde başlatılıyor nesneler yığını gibi, bu değişkenler dışarı kapsamı, yıkıcılar otomatik olarak denir neden olan kaynakları temizlenmelidir.

Neden denmiyor "kullanarak temizleme tetiklemek için yığın" (UTSTTC:)? Nasıl oradan musun ""? DEMİRYOLU

Nasıl bir şey bu öbek üzerinde oturan bir temizleme neden olur yığın yapabilir misin? Ayrıca, DEMİRYOLU kullanamazsın durumlar vardır? Hiç çöp toplama için kendini isteyen buluyor musunuz? Diğerleri yönetilmesi izin verirken, bazı nesneler için kullanabilirsin en azından bir çöp toplayıcı?

Teşekkürler.

CEVAP
3 NİSAN 2009, Cuma


Neden denmiyor "kullanarak temizleme tetiklemek için yığın" (UTSTTC:)?

DEMİRYOLU ne: sana bir kurucu kaynak Elde! Eklemek istiyorum: bir kaynak, bir kurucu. UTSTTC çok daha fazla DEMİRYOLU olan bir uygulama.

Kaynak Yönetimi berbat.Burada, kaynak kullanım sonrası temizleme ihtiyacı olan bir şey. Birçok platformda proje çalışmaları hataların çoğunluğu kaynak yönetimi ile ilgili Haritayı - ve Windows (nesneler ve yöneticileri birçok türleri nedeniyle) özellikle kötü.

C , kaynak yönetimi özel durumlar ve (C tipi) şablonları kombinasyonu sayesinde özellikle karmaşıktır. Kaputun altında bir göz, GOTW8).


C yıkıcı denir güvence altına alırEğer ve sadece eğerkurucu başardı. Buna dayanarak, DEMİRYOLU çok kötü sorunları çözebilir ortalama programcı bile farkında olmayabilir. Burada ötesinde birkaç örnek "benim yerel değişkenler döndüğüm zaman yok olacak".

Bize DEMİRYOLU çalışanı: aşırı basit FileHandle sınıfı ile başlayalım

class FileHandle
{
    FILE* file;

public:

    explicit FileHandle(const char* name)
    {
        file = fopen(name);
        if (!file)
        {
            throw "MAYDAY! MAYDAY";
        }
    }

    ~FileHandle()
    {
        // The only reason we are checking the file pointer for validity
        // is because it might have been moved (see below).
        // It is NOT needed to check against a failed constructor,
        // because the destructor is NEVER executed when the constructor fails!
        if (file)
        {
            fclose(file);
        }
    }

    // The following technicalities can be skipped on the first read.
    // They are not crucial to understanding the basic idea of RAII.
    // However, if you plan to implement your own RAII classes,
    // it is absolutely essential that you read on :)



    // It does not make sense to copy a file handle,
    // hence we disallow the otherwise implicitly generated copy operations.

    FileHandle(const FileHandle&) = delete;
    FileHandle& operator=(const FileHandle&) = delete;



    // The following operations enable transfer of ownership
    // and require compiler support for rvalue references, a C  0x feature.
    // Essentially, a resource is "moved" from one object to another.

    FileHandle(FileHandle&& that)
    {
        file = that.file;
        that.file = 0;
    }

    FileHandle& operator=(FileHandle&& that)
    {
        file = that.file;
        that.file = 0;
        return *this;
    }
}

İnşaat başarısız (bir istisna ile), başka bir üye işlevi - yıkıcı değil, hatta çağrılır.

DEMİRYOLU geçersiz bir durumda nesneleri kullanarak önler.zaten biz bile nesneyi kullanmadan önce hayatı kolaylaştırır.

Şimdi, bize geçici nesneler bir göz atalım:

void CopyFileData(FileHandle source, FileHandle dest);

void Foo()
{
    CopyFileData(FileHandle("C:\\source"), FileHandle("C:\\dest"));
}

Herhangi bir dosya açılabilir, tek bir dosya açılabilir, her iki dosya açılabilir ama dosya kopyalama işlemi başarısız oldu. işlenen üç hata durum vardır: Olmayan DEMİRYOLU, Foo bir uygulama işlemek için her üç durumda açıkça.

DEMİRYOLU birden fazla kaynak bir deyim içinde edinilen bile elde olan kaynakları serbest bırakır.

Şimdi, bize bazı nesneler toplamak

class Logger
{
    FileHandle original, duplex;   // this logger can write to two files at once!

public:

    Logger(const char* filename1, const char* filename2)
    : original(filename1), duplex(filename2)
    {
        if (!filewrite_duplex(original, duplex, "New Session"))
            throw "Ugh damn!";
    }
}

Kurucu Logger başarısız original'nin kurucu başarısız (çünkü filename1 değil, açık), duplex'nin kurucu başarısız (çünkü filename2 değil açılır) ya da yazı dosyaları içinde Logger'nin kurucu beden başarısız. Bu durumlardan herhangi biri, Logger's yıkıcı olacaktırdeğilLogger'dosyaları serbest yıkıcı. itimat edemeyiz sözde - Ama eğer original yapılmış olsaydı, kendi yıkıcı Logger kurucu temizleme sırasında çağrılır.

DEMİRYOLU kısmi inşaat sonrası temizliği kolaylaştırır.


Negatif puan

Eksi puan mı? Tüm sorunları DEMİRYOLU ve akıllı işaretçiler ile çözülebilir ;-)

DEMİRYOLU gecikmeli edinme ihtiyacınız olduğunda bazen hantal, öbek üzerine toplanan nesneleri bastırıyor.
Logger SetTargetFile(const char* target) bir ihtiyaç düşünün. Bu durumda, idare, hala gerekiyor üye Logger, ihtiyaçlarına bulunan öbek (örneğin bir akıllı işaretçi, tetik kolu yok edilmesi gerektiği gibi.)

Asla çöp toplama için gerçekten diledim. C# ben bir anlık mutluluktan umurumda değil, ama çok daha fazla hissediyorum bazen ben ne zaman deterministik imha yoluyla oluşturulan bütün havalı oyuncaklar özledim. (IDisposable kullanarak sadece kesmiyor.)

GC yararlanmış olabilir, "basit" akıllı işaretçiler birden fazla sınıflar. döngüsel başvurular neden olur özellikle karmaşık bir yapısı vardı Üzerinden dikkatli bir şekilde güçlü ve zayıf işaretçiler dengeleyerek biz kafası karışık, ama bir şey değiştirmek istediğimiz zaman, büyük bir ilişki grafik çalışmak zorundayız. GC daha iyi olabilirdi, ama bu bileşenlerin bazıları bırakın en kısa sürede gereken kaynakları düzenledi.


FileHandle örnek üzerinde bir not: tam, sadece bir örnek olması amaçlanmıştır değildi ama yanlış çıktı. Teşekkürler işaret ve doğru C 0 x çözüm dönüşmesi için FredOverflow için Schaub Johannes. Zaman içinde bu yaklaşım documented here ile yaşadım.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Android Developers

    Android Deve

    9 Kasım 2007
  • B3ASTTY™

    B3ASTTY™

    27 Mayıs 2013
  • Howard Pinsky

    Howard Pinsk

    6 AĞUSTOS 2006