Risi dhe fshij (C++)
p = new T(argument);
Në gjuhën e programimit C++ , dhe janë një çift i konstrukteve gjuhësore që kryejnë shpërndarje dinamike të memories, ndërtimin e objektit dhe shkatërrimin e objektit . [1]
Vështrim i përgjithshëm
RedaktoPërveç një forme të quajtur "vendosje e re", the operatori tregon një kërkesë për shpërndarje memorie në grumbullin e një procesi. Nëse disponohet memorie e mjaftueshme, inicializon memorien, duke thirrur konstruktorët e objekteve nëse është e nevojshme, dhe e kthen adresën në memorien e re të alokuar dhe të inicializuar. [2] [3] A kërkesa , në formën e saj më të thjeshtë, duket si më poshtë:
p = new T [N];
ku është një tregues i tipit i deklaruar më parë (ose ndonjë lloj tjetër për të cilin a Treguesi mund të caktohet, si p.sh. një superklasë e ). Konstruktori i paracaktuar për , nëse ka, thirret për të ndërtuar a Shembull në buferin e ndarë të memories.
Nëse jo është instaluar, në vend të kësaj hedh një përjashtim të llojit . Kështu, programi nuk ka nevojë të kontrollojë vlerën e treguesit të kthyer, siç është zakon në C ; nëse nuk bëhej përjashtim, shpërndarja kishte sukses.
Homologu i shpërndarjes së eshte , i cili fillimisht thërret destruktorin (nëse ka) në argumentin e tij dhe më pas kthen memorien e alokuar nga në dyqanin falas. Çdo thirrje për duhet të përputhet me një telefonatë në ; dështimi për ta bërë këtë shkakton një rrjedhje të kujtesës . [1]
syntax has several variants that allow finer control over memory allocation and object construction. A function call-like syntax is used to call a different constructor than the default one and pass it arguments, e.g.,
p = new T[N] {initializer1, ..., initializerN};
quan një argument të vetëm Konstruktori në vend të konstruktorit të paracaktuar kur inicializon buferin e sapondarë. Një variant i ndryshëm shpërndan dhe inicializon vargjet e objekteve në vend të objekteve të vetme:
#include <cstdlib>
#include <cstddef>
class Singleton {
public:
static void* operator new(std::size_t size) {
if (!instance) {
instance = std::malloc(size);
}
refcount++;
return instance;
}
static void operator delete(void*) noexcept {
if (--refcount == 0) {
std::free(instance);
instance = nullptr;
}
}
private:
static void* instance = nullptr;
static std::size_t refcount = 0;
};
Kjo kërkon një tampon memorie nga dyqani falas që është mjaft i madh për të mbajtur një grup të afërt objekte të tipit , dhe thërret konstruktorin e paracaktuar në çdo element të grupit.
Memoria e alokuar me duhet të shpërndahet me , në vend të . Përdorimi i formës së papërshtatshme rezulton në sjellje të papërcaktuar . Përpiluesit C++ nuk kërkohet të gjenerojnë një mesazh diagnostikues për përdorimin e formularit të gabuar.
Standardi C++11 specifikon një sintaksë shtesë,
p = new T;
që inicializon secilën .
Trajtimi i gabimeve
RedaktoNëse nuk mund të gjejë memorie të mjaftueshme për të shërbyer një kërkesë alokimi, ajo mund të raportojë gabimin e saj në tre mënyra të ndryshme. Së pari, standardi ISO C++ lejon programet të regjistrojnë një funksion të personalizuar të quajtur a me kohën e ekzekutimit në C++; nëse po, atëherë ky funksion thirret kurdoherë ndeshet me një gabim. Të mund të përpiqet të ofrojë më shumë memorie ose të përfundojë programin nëse nuk mundet.
Nëse nuk ka memorie të mjaftueshme në dyqanin falas për një objekt të llojit , të kërkesa tregon dështimin duke hedhur një përjashtim të llojit . Kjo heq nevojën për të kontrolluar në mënyrë eksplicite rezultatin e një alokimi.
Metoda e tretë e trajtimit të gabimeve sigurohet nga forma e variantit , i cili specifikon se nuk duhet hedhur asnjë përjashtim; në vend të kësaj, një tregues null kthehet për të sinjalizuar një gabim shpërndarjeje.
Mbingarkim
RedaktoTë operatori mund të mbingarkohet në mënyrë që lloje të veçanta (klasa) të përdorin algoritme të shpërndarjes së memories të personalizuara për instancat e tyre. Për shembull, në vijim është një variant i modelit singleton ku i pari Thirrja alokon një shembull dhe të gjitha thirrjet pasuese kthejnë të njëjtin shembull:
- ^ a b Savitch, Walter (2013). Absolute C++. Pearson. fq. 420–445. ISBN 978-0132846813.
{{cite book}}
: Mungon ose është bosh parametri|language=
(Ndihmë!) - ^ "IBM Documentation describing C++'s operator new". Arkivuar nga origjinali më 2013-01-03. Marrë më 2013-11-06.
{{cite web}}
: Mungon ose është bosh parametri|language=
(Ndihmë!) - ^ "Microsoft Visual Studio operator new documentation". Marrë më 2013-11-06.
{{cite web}}
: Mungon ose është bosh parametri|language=
(Ndihmë!)
Kjo veçori ishte e disponueshme që herët në historinë e C++, megjithëse mekanizmi specifik i mbingarkesës ndryshoi. Ajo u shtua në gjuhë sepse programet C++ të orientuara drejt objekteve prireshin të ndanin shumë objekte të vogla me , e cila përdori përbrenda alokatorin C (shih § Relation to malloc and free ); që, megjithatë, ishte optimizuar për alokimet më të pakta dhe më të mëdha të kryera nga programet tipike C. Stroustrup raportoi se në aplikimet e hershme, funksioni C ishte "blloku më i zakonshëm i performancës në sistemet reale", me programet që shpenzonin deri në 50% të kohës së tyre në këtë funksion. [4]
Lidhja me malloc dhe pa pagesë
RedaktoMeqenëse standardi C++ përfshin bibliotekën standarde C, rutinat e ndarjes së memories dinamike C , , dhe janë gjithashtu të disponueshme për programuesit C++. Përdorimi i këtyre rutinave është i dekurajuar për shumicën e përdorimeve, pasi ato nuk kryejnë inicializimin dhe shkatërrimin e objektit. [1] të reja dhe , në fakt, u prezantuan në versionin e parë të C++ (atëherë i quajtur " C me klasa ") për të shmangur domosdoshmërinë e inicializimit manual të objektit.
Në ndryshim nga rutinat C, të cilat lejojnë rritjen ose tkurrjen e një grupi të caktuar me , nuk është e mundur të ndryshohet madhësia e një buferi memorie të alokuar nga . Në vend të kësaj, biblioteka standarde C++ ofron një grup (koleksion) dinamik që mund të zgjerohet ose zvogëlohet në të Klasa e shabllonit .
Standardi C++ nuk specifikon asnjë lidhje ndërmjet / dhe rutinat e ndarjes së memories C, por dhe zakonisht zbatohet si mbështjellës përreth dhe . [2] Përzierja e dy familjeve të operacioneve, p.sh. kujtesa e alokuar ose 'ing memoria , shkakton sjellje të padefinuar dhe në praktikë mund të çojë në rezultate të ndryshme katastrofike si mos lirimi i bravave dhe rrjedhimisht bllokimi . [3]
Shihni gjithashtu
Redakto- Përcaktues (C++)
- Trajtimi me përjashtim
- Pishina e memories
- Pointer (programim kompjuterik)
- Përvetësimi i burimeve është inicializimi (RAII)
- Tregues të zgjuar
Referencat
Redakto- ^ Meyers, Scott (1998). Effective C++. Addison-Wesley. fq. 21. ISBN 9780201924886.
{{cite book}}
: Mungon ose është bosh parametri|language=
(Ndihmë!) - ^ Alexandrescu, Andrei (2001). Modern C++ Design: Generic Programming and Design Patterns Applied. Addison-Wesley. fq. 68.
{{cite book}}
: Mungon ose është bosh parametri|language=
(Ndihmë!) - ^ Seacord, Robert C. (2013). Secure Coding in C and C++. Addison-Wesley.
{{cite book}}
: Mungon ose është bosh parametri|language=
(Ndihmë!) Section 4.4, Common C++ Memory Management Errors.
Stampa:C++ programming languageStampa:Memory management navboxStampa:Programming languages