SORU
25 AĞUSTOS 2011, PERŞEMBE


Nasıl Standart uyumlu özel ISO C new ve delete operatörleri yazayım mı?

Nasıl ISO C standardı uyumlu özel new delete operatörler yazayım mı?

Bu son derece aydınlatıcı C SSS Overloading new and delete devamı, Operator overloading ve takip, Why should one replace default new and delete operators?

Bölüm 1:Yazılı standart-uyumlu new bir operatör

Bölüm 2:Yazılı standart-uyumlu delete bir operatör

(Not: Bu Stack Overflow's C FAQ için bir giriş olarak tasarlanmıştır. Eğer bu formda bir SSS sağlama fikri tenkit etmek istiyorsanız, o zaman the posting on meta that started all this bunu yapmak için bir yer olurdu. Cevaplar soru izlenen C chatroom nereye SSS fikir başladı ilk başta, bu da senin cevabın çok muhtemel alın okuyun o kim buldu bu fikri.)
Not: cevap Scott Meyers dan öğrendiklerini Daha Etkili C ve ISO Standart C dayanır.

CEVAP
25 AĞUSTOS 2011, PERŞEMBE


Bölüm I

This C FAQ entry açıkladınedenkendi sınıfı için new delete operatörlerin aşırı isteyebilirsiniz. Bu hediye SSS açıklamaya çalışırnasılbu yüzden standart-uygun bir şekilde yapar.

Uygulamaya özel new operatör

C standart (§18.4.1.1) operator new olarak tanımlar:

void* operator new (std::size_t size) throw (std::bad_alloc);

C standardı bu operatörler özel sürümleri §3.7.3 itaat ve §18.4.1 olan semantik belirtir

Bize şartları özetleyelim.

İhtiyaç #1:Dinamik olarak en az bellek size bayt ayırmak ve ayrılan bellek için bir işaretçi dönmek gerekir. C standardı alıntı, bölüm 3.7.4.1.3:

Ayırma depolama talep miktarı ayırmaya çalışır. Eğer başarılı olursa, bayt cinsinden istenilen boyut olarak en az büyük olanı depolama bloğunun başlangıç adresi geri verir...

Standart daha getirir:

...İşaretçiyi iade edilecektir uygun hizada olması dönüştürülmüş bir işaretçi herhangi bir tam nesne türü ve kullanılan erişim nesne ya da dizi depolama ayrılan (kadar depolama açıkça ayırmanın bir çağrı için bir karşılık gelen miktarda kaldırma işlevi). Eğer uzay talep boyutunu sıfır değilse bile, isteği başarısız olabilir. Eğer isteği başarılı olursa, döndürülen değer olacaktır olmayan bir null işaretçi değeri (4.10) p0 farklı herhangi bir önceden döndürülen değeri p1, sürece bu değeri p1 alt sequently geçirilen bir operatör delete.

Bu bizi daha da önemli gereksinimler verir:

İhtiyaç #2:Kullandığımız bellek ayırma fonksiyonu (genellikle malloc() veya başka bir özel ayırıcı) dönmelidiruygun şekilde hizalanmıştam bir nesne türünü gösteren bir işaretçi çevrilir ve nesne erişimi için kullanılan ayrılmış bellek işaretçisi.

İhtiyaç #3:Özel görevlimiz 16* *sıfır bayt olunur hatta meşru bir işaretçi dönmek gerekir.

Hatta new prototip anlamında da görüleceği belli şartlardan biri:

İhtiyaç #4:Eğer new istenen boyutta dinamik bellek varsa, o zaman bir özel durum türü std::bad_alloc atmak gerekir.

Ama!Göze çarpandan daha fazlası var: 48 ** new operatör (standart alıntı daha aşağı aşağıda) daha yakından bir göz atacak olursak, bu devletler:

Eğerset_new_handlerbir tanımlamak için kullanılmıştırnew_handlerfonksiyon new_handler Bu fonksiyon kendi tarafından ise istenen depolama ayırma işlemi operator new standart varsayılan tanım olarak adlandırılır.

Bizim özel new bu gereksinimi desteklemek için ihtiyacı anlamak için, anlamak gerekir:

new_handler set_new_handler nedir?

new_handler ve hiçbir şey alır döndüren bir işlev için bir işaretçi için bir typedef, set_new_handler new_handler alır döndüren bir işlevdir.

set_new_handler'ın yeni parametre eğer istenen hafıza tahsis edebilirsiniz, mi demeliyim fonksiyon operatör için bir işaretçi. Dönüş değeri, daha önce kayıtlı işleyici işlevi için bir işaretçi veya bir önceki işleyicisi olsaydı orada hiçbir boş.

Net şeyler yapmak için kod örneği için bir fırsat anı:

#include <iostream>
#include <cstdlib>

// function to call if operator new can't allocate enough memory or error arises
void outOfMemHandler()
{
    std::cerr << "Unable to satisfy request for memory\n";

    std::abort();
}

int main()
{
    //set the new_handler
    std::set_new_handler(outOfMemHandler);

    //Request huge memory size, that will cause ::operator new to fail
    int *pBigDataArray = new int[100000000L];

    return 0;
}

Yukarıdaki örnekte, operator new (büyük olasılıkla) mümkün tahsis alanı için 100,000,000 tamsayılar ve işlevi outOfMemHandler() denir ve program iptal olacak sonra issuing an error message.

Önemli operator new bellek isteği yerine getirmek için mümkün olduğunda, new-handler işlevi kadar sürekli onu çağıran burada dikkat etmek önemlidirolabiliryeterli bellek bulmak ya da yeni işleyicileri vardır. Dediğimiz sürece yukarıdaki örnekte, std::abort(), outOfMemHandler() called repeatedly olurdu. Bu nedenle, işleyicisi ya da bir sonraki ayırma başarılı olmasını sağlamak, ya da başka bir işleyicisi kaydetmek, ya da hiç işleyicisi kaydetmek gerekir, ya da geri dönmek yok (yani programı sonlandırmak). Yeni işleyicisi yok ve ayırma başarısız olursa, operatör, bir özel durum oluşturur.

Continuation 1


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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • eisleyhead

    eisleyhead

    11 Ocak 2006
  • SegaAmerica

    SegaAmerica

    5 Mart 2008
  • Trevor Eckhart

    Trevor Eckha

    19 Aralık 2009