├ť├ž├╝n Kural─▒ Nedir?


Al─▒nan cevaba git


  • Ne gelmez bir nesne kopyalama ortalama?
  • Nelerdir kopya yap─▒c─▒ ve kopya atama operat├Âr├╝ ?
  • Onlar─▒ kendim ilan etmem ne zaman gerekir?
  • Nesnelerimin kopyalanmas─▒n─▒ nas─▒l ├Ânleyebilirim?

2058









Cevap say─▒s─▒n─▒ say: 8






Giri┼č

C ++, kullan─▒c─▒ tan─▒ml─▒ t├╝rlerin de─či┼čkenlerini de─čer anlam─▒nda ele al─▒r . Bu, nesnelerin dolayl─▒ olarak ├že┼čitli ba─člamlarda kopyaland─▒─č─▒ ve ÔÇťbir nesneyi kopyalaman─▒nÔÇŁ ger├žekte ne anlama geldi─čini anlamam─▒z gerekti─či anlam─▒na gelir.

Basit bir ├Ârnek ele alal─▒m:

 class person
{
    std::string name;
    int age;

public:

    person(const std::string& name, int age) : name(name), age(age)
    {
    }
};

int main()
{
    person a("Bjarne Stroustrup", 60);
    person b(a);   // What happens here?
    b = a;         // And here?
}
 

( name(name), age(age) Par├ža taraf─▒ndan ┼ča┼č─▒r─▒yorsan─▒z , buna ├╝ye ba┼člat─▒c─▒ listesi denir .)

├ľzel ├╝ye fonksiyonlar─▒

Bir person nesneyi kopyalamak ne demektir ? main Fonksiyonu, iki farkl─▒ kopyalama senaryolar─▒ g├Âstermektedir. Ba┼člatma person b(a); , kopya kurucu taraf─▒ndan ger├žekle┼čtirilir . G├Ârevi, mevcut bir nesnenin durumuna g├Âre yeni bir nesne in┼ča etmektir. Atama b = a , kopya atama operat├Âr├╝ taraf─▒ndan ger├žekle┼čtirilir . ─░┼či genellikle biraz daha karma┼č─▒kt─▒r, ├ž├╝nk├╝ hedef nesne zaten ele al─▒nmas─▒ gereken ge├žerli bir durumdad─▒r.

Ne kopya kurucuyu ne de atama operat├Âr├╝n├╝ (ne de y─▒k─▒c─▒y─▒) kendimizi ilan etmedi─čimiz i├žin, bunlar bizim i├žin kesin olarak tan─▒mlanm─▒┼čt─▒r. Standarttan al─▒nt─▒:

[...] kopya yap─▒c─▒ ve kopya atama operat├Âr├╝, [...] ve y─▒k─▒c─▒ ├Âzel ├╝ye i┼člevleridir. [ Not : Uygulama a├ž─▒k├ža program─▒n a├ž─▒klamamas─▒ halinde baz─▒ s─▒n─▒f tipleri i├žin bu ├╝ye i┼člevlerini dolayl─▒ olarak ilan edecektir. Uygulama, kullan─▒lmalar─▒ halinde dolayl─▒ olarak tan─▒mlayacakt─▒r. [...] son not ] [n3126.pdf b├Âl├╝m 12 ┬ž1]

Varsay─▒lan olarak, bir nesneyi kopyalamak, ├╝yelerini kopyalamak anlam─▒na gelir:

Sendika olmayan bir s─▒n─▒f X i├žin dolayl─▒ olarak tan─▒mlanm─▒┼č kopya kurucu, alt nesnelerinin ├╝ye olarak bir kopyas─▒n─▒ ger├žekle┼čtirir. [n3126.pdf b├Âl├╝m 12.8 ┬ž16]

Sendika olmayan bir s─▒n─▒f X i├žin dolayl─▒ olarak tan─▒mlanm─▒┼č kopya atama operat├Âr├╝, alt nesnelerinin ├╝ye olarak kopya atama i┼člemini ger├žekle┼čtirir. [n3126.pdf b├Âl├╝m 12.8 ┬ž30]

├ľrt├╝k tan─▒mlar

├ľrt├╝k tan─▒ml─▒ ├Âzel ├╝ye person ┼čuna benzer:

 // 1. copy constructor
person(const person& that) : name(that.name), age(that.age)
{
}

// 2. copy assignment operator
person& operator=(const person& that)
{
    name = that.name;
    age = that.age;
    return *this;
}

// 3. destructor
~person()
{
}
 

├ťye olarak kopyalamak tam da bu durumda istedi─čimiz ┼čeydir: name ve age kopyalan─▒r, bu nedenle ba─č─▒ms─▒z, ba─č─▒ms─▒z bir person nesne elde ederiz . ├ľrt├╝k tan─▒ml─▒ y─▒k─▒c─▒ her zaman bo┼čtur. Bu, bu durumda da iyidir, ├ž├╝nk├╝ yap─▒c─▒da herhangi bir kaynak edinmedik. person Y─▒k─▒c─▒ bittikten sonra ├╝yelerin y─▒k─▒c─▒lar─▒ dolayl─▒ olarak ├ža─čr─▒l─▒r :

Y─▒k─▒c─▒ g├Âvdesini y├╝r├╝tt├╝kten ve v├╝cut i├žine tahsis edilen herhangi bir otomatik nesneyi yok ettikten sonra, X s─▒n─▒f─▒ i├žin bir y─▒k─▒c─▒, X'in do─črudan [...] ├╝yeleri i├žin y─▒k─▒c─▒lar olarak adland─▒r─▒r [n3126.pdf 12.4 ┬ž6]

Kaynaklar─▒ y├Ânetme

Peki, bu ├Âzel ├╝ye i┼člevleri ne zaman a├ž─▒k├ža ilan etmeliyiz? S─▒n─▒f─▒m─▒z bir kayna─č─▒ y├Ânetti─činde , yani s─▒n─▒f─▒n bir nesnesi o kaynaktan sorumlu oldu─ču zaman . Bu genellikle, kayna─č─▒n yap─▒c─▒dan elde edildi─či (veya yap─▒c─▒ya iletildi─či) ve y─▒k─▒c─▒da serbest b─▒rak─▒ld─▒─č─▒ anlam─▒na gelir .

├ľnceden standart C ++ 'ya geri d├Ânelim. ├ľyle bir ┼čey yoktu std::string ve programc─▒lar i┼čaret├žilere ├ó┼č─▒kt─▒. person S─▒n─▒f bu benziyordu olabilir:

 class person
{
    char* name;
    int age;

public:

    // the constructor acquires a resource:
    // in this case, dynamic memory obtained via new[]
    person(const char* the_name, int the_age)
    {
        name = new char[strlen(the_name) + 1];
        strcpy(name, the_name);
        age = the_age;
    }

    // the destructor must release this resource via delete[]
    ~person()
    {
        delete[] name;
    }
};
 

Bug├╝n bile, hala insanlar yazma s─▒n─▒flar─▒ bu tarzda ve belaya: " Ben bir vekt├Âr i├žerisine bir ki┼či itti ve ┼čimdi deli haf─▒za hatalar─▒ olsun! " Varsay─▒lan olarak, ├╝yelerini kopyalan─▒rken bir nesne ara├žlar─▒n─▒ kopyalama, ancak kopyalama unutmay─▒n name sadece ├╝ye kopyalar bir i┼čaret├ži, de─čil karakter dizisi o i┼čaret! Bunun baz─▒ ho┼č olmayan etkileri var:

  1. ─░le yap─▒lan de─či┼čiklikler ile a g├Âzlemlenebilir b .
  2. Bir kez b yok edildi, a.name sarkan bir i┼čaret├ži.
  3. a Yok edilirse , sarkan i┼čaret├žiyi silmek, tan─▒ms─▒z davran─▒┼ča yol a├žar .
  4. name ├ľdev, ├Âdevden ├Ânce g├Âsterilenleri hesaba katmad─▒─č─▒ndan er ya da ge├ž her yerde bellek s─▒z─▒nt─▒lar─▒ g├Âreceksiniz.

A├ž─▒k tan─▒mlar

├ťyeye g├Âre kopyalama istenen etkiye sahip olmad─▒─č─▒ndan, karakter dizisinin derin kopyalar─▒n─▒ almak i├žin kopya yap─▒c─▒s─▒n─▒ ve kopya atama operat├Âr├╝n├╝ a├ž─▒k├ža tan─▒mlamal─▒y─▒z:

 // 1. copy constructor
person(const person& that)
{
    name = new char[strlen(that.name) + 1];
    strcpy(name, that.name);
    age = that.age;
}

// 2. copy assignment operator
person& operator=(const person& that)
{
    if (this != &that)
    {
        delete[] name;
        // This is a dangerous point in the flow of execution!
        // We have temporarily invalidated the class invariants,
        // and the next statement might throw an exception,
        // leaving the object in an invalid state :(
        name = new char[strlen(that.name) + 1];
        strcpy(name, that.name);
        age = that.age;
    }
    return *this;
}
 

Ba┼člatma ve atama aras─▒ndaki farka dikkat edin: name bellek s─▒z─▒nt─▒lar─▒n─▒ ├Ânlemek i├žin atamadan ├Ânce eski durumunu y─▒rt─▒yoruz. Ayr─▒ca, formun kendili─činden atanmas─▒na kar┼č─▒ korunmal─▒y─▒z x = x . O ├žek olmadan, delete[] name i├žeren diziyi silmek istiyorsunuz kaynak yazd─▒─č─▒n─▒z zaman, ├ž├╝nk├╝ dize x = x , hem this->name ve that.name ayn─▒ i┼čaret├ži i├žerir.

─░stisna g├╝venlik

Ne yaz─▒k ki, new char[...] bellek t├╝kenmesi nedeniyle bir istisna atarsa bu ├ž├Âz├╝m ba┼čar─▒s─▒z olur . Olas─▒ bir ├ž├Âz├╝m, yerel bir de─či┼čken tan─▒tmak ve ifadeleri yeniden s─▒ralamakt─▒r:

 // 2. copy assignment operator
person& operator=(const person& that)
{
    char* local_name = new char[strlen(that.name) + 1];
    // If the above statement throws,
    // the object is still in the same state as before.
    // None of the following statements will throw an exception :)
    strcpy(local_name, that.name);
    delete[] name;
    name = local_name;
    age = that.age;
    return *this;
}
 

Bu ayn─▒ zamanda a├ž─▒k bir kontrol olmadan kendi kendine atamay─▒ da ├Ânemser. Bu soruna daha sa─člam bir ├ž├Âz├╝m, kopyala ve de─či┼čtir deyimdir , ancak burada istisnai g├╝venlik detaylar─▒na girmeyece─čim. Sadece ┼ču noktaya de─činmek i├žin istisnalardan bahsettim: Kaynaklar─▒ y├Âneten s─▒n─▒flar yazmak zor.

Sorumsuz kaynaklar

Dosya tan─▒t─▒c─▒lar─▒ veya muteksler gibi baz─▒ kaynaklar kopyalanamaz veya kopyalanmamal─▒d─▒r. Bu durumda, kopya yap─▒c─▒s─▒n─▒ ve kopya atamas─▒ i┼člecini private tan─▒m vermeden tan─▒mlaman─▒z yeterlidir :

 private:

    person(const person& that);
    person& operator=(const person& that);
 

Alternatif olarak, bunlar─▒ sildirebilir boost::noncopyable veya silinmi┼č olarak beyan edebilirsiniz (C ++ 11 ve ├╝st├╝):

 person(const person& that) = delete;
person& operator=(const person& that) = delete;
 

├ť├ž kural─▒

Bazen bir kayna─č─▒ y├Âneten bir s─▒n─▒f uygulaman─▒z gerekir. (Asla tek bir s─▒n─▒fta birden fazla kayna─č─▒ y├Ânetmeyin, bu yaln─▒zca ac─▒ verir.) Bu durumda, ├╝├ž├╝n kural─▒n─▒ unutmay─▒n :

Y─▒k─▒c─▒, kopya kurucu veya kopya atama operat├Âr├╝n├╝ a├ž─▒k├ža beyan etmeniz gerekiyorsa, muhtemelen bunlar─▒n ├╝├ž├╝n├╝ de a├ž─▒k├ža beyan etmeniz gerekir.

(Ne yaz─▒k ki, bu "kural", C ++ standard─▒ veya bildi─čim herhangi bir derleyici taraf─▒ndan uygulanmamaktad─▒r.)

Be┼č kural─▒

C ++ 11'den itibaren, bir nesnenin 2 ├Âzel ├╝ye i┼člevi vard─▒r: ta┼č─▒ma yap─▒c─▒s─▒ ve ta┼č─▒ma atamas─▒. Bu fonksiyonlar─▒ uygulamak i├žin be┼č devletin kural─▒.

─░mzalara bir ├Ârnek:

 class person
{
    std::string name;
    int age;

public:
    person(const std::string& name, int age);        // Ctor
    person(const person &) = default;                // Copy Ctor
    person(person &&) noexcept = default;            // Move Ctor
    person& operator=(const person &) = default;     // Copy Assignment
    person& operator=(person &&) noexcept = default; // Move Assignment
    ~person() noexcept = default;                    // Dtor
};
 

S─▒f─▒r kural─▒

3/5 kural─▒ ayr─▒ca 0/3/5 kural─▒ olarak da adland─▒r─▒l─▒r. Kural─▒n s─▒f─▒r k─▒sm─▒, s─▒n─▒f─▒n─▒z─▒ olu┼čtururken ├Âzel ├╝ye i┼člevlerinden hi├žbirini yazmaman─▒za izin verilmedi─čini belirtir.

Tavsiye

├ço─ču zaman, bir kayna─č─▒ kendiniz y├Ânetmenize gerek yoktur, ├ž├╝nk├╝ std::string zaten mevcut bir s─▒n─▒f sizin i├žin yapar. Sadece basit bir kodu kullanarak bir std::string ├╝ye kullanarak, bir char* ve kullanarak ikna olmal─▒s─▒n─▒z. Ham i┼čaret├ži ├╝yelerinden uzak durdu─čunuz s├╝rece, ├╝├ž kural─▒n kendi kodunuzla ilgisi yoktur.


1703







├ť├ž Kural─▒ C ++ i├žin pratik bir kurald─▒r, temelde s├Âyleyerek

S─▒n─▒f─▒n─▒z─▒n herhangi birine ihtiyac─▒ varsa

  • bir kopya kurucu ,
  • bir atama operat├Âr├╝ ,
  • veya bir y─▒k─▒c─▒ ,

a├ž─▒k├ža tan─▒mland─▒─č─▒nda , bunlar─▒n ├╝├ž├╝ne de ihtiya├ž duyulmas─▒ muhtemeldir .

Bunun nedeni, ├╝├ž├╝n├╝n de genellikle bir kayna─č─▒ y├Ânetmek i├žin kullan─▒lmas─▒d─▒r ve s─▒n─▒f─▒n─▒z bir kayna─č─▒ y├Ânetiyorsa, genellikle kopyalaman─▒n yan─▒ s─▒ra serbest b─▒rakmay─▒ da y├Ânetmesi gerekir.

S─▒n─▒f─▒n─▒z─▒n y├Ânetti─či kayna─č─▒ kopyalamak i├žin iyi bir semantik yoksa , kopya kurucusunu ve atama i┼člecini olarak tan─▒mlayarak ( tan─▒mlayarak ) kopyalamay─▒ yasaklamay─▒ d├╝┼č├╝n├╝n private .

(C ++ standard─▒n─▒n yeni ├ž─▒kacak s├╝r├╝m├╝n├╝n (C ++ 11 olan), ├╝├ž kural─▒n─▒ de─či┼čtirebilecek b├╝y├╝k olas─▒l─▒kla C ++ 'a hareket anlam─▒n─▒ ekledi─čine dikkat edin. Bununla birlikte, C ++ 11 b├Âl├╝m├╝n├╝ yazmak i├žin ├žok az ┼čey biliyorum. ├ť├ž Kural─▒ hakk─▒nda.)


487


2010-11-13





B├╝y├╝k ├╝├ž├╝n├╝n yasas─▒ yukar─▒da belirtildi─či gibidir.

Basit ─░ngilizce'de ├ž├Âzd├╝─č├╝ t├╝rden bir problem:

Varsay─▒lan olmayan y─▒k─▒c─▒

Yap─▒c─▒n─▒za bellek tahsis ettiniz ve bu y├╝zden silmek i├žin bir y─▒k─▒c─▒ yazman─▒z gerekiyor. Aksi takdirde, bellek s─▒z─▒nt─▒s─▒na neden olursunuz.

Bunun bir i┼č oldu─čunu d├╝┼č├╝nebilirsiniz.

Sorun, nesnenizden bir kopya yap─▒lm─▒┼čsa, kopya orijinal nesneyle ayn─▒ haf─▒zay─▒ g├Âsterecektir.

Bunlardan biri y─▒k─▒c─▒daki haf─▒zay─▒ silerken, di─čeri ge├žersiz haf─▒zan─▒n bir g├Âstergesine sahip olacakt─▒r (buna sarkan bir i┼čaret├ži denir), kullanmaya ├žal─▒┼čt─▒─č─▒nda i┼čler k─▒ll─▒ hale gelir.

Bu nedenle, bir kopya kurucu yazar, b├Âylece yeni nesnelere yok etmek i├žin kendi haf─▒za par├žalar─▒n─▒ tahsis eder.

Atama operat├Âr├╝ ve kopya kurucusu

Yap─▒c─▒n─▒zdaki haf─▒zay─▒, s─▒n─▒f─▒n─▒z─▒n bir i┼čaret├žisi ├╝zerine tahsis ettiniz. Bu s─▒n─▒f─▒n bir nesnesini kopyalad─▒─č─▒n─▒zda, varsay─▒lan atama operat├Âr├╝ ve copy yap─▒c─▒s─▒ bu ├╝ye i┼čaret├žisinin de─čerini yeni nesneye kopyalar.

Bu, yeni nesnenin ve eski nesnenin ayn─▒ haf─▒za par├žas─▒n─▒ g├Âsterece─či anlam─▒na gelir, b├Âylece onu bir nesnede de─či┼čtirdi─činizde di─čer nesne i├žin de de─či┼čecektir. Bir nesne bu haf─▒zay─▒ silerse, di─čeri onu kullanmay─▒ denemeye devam eder - eek.

Bunu ├ž├Âzmek i├žin, kopya kurucu ve atama operat├Âr├╝n├╝n kendi versiyonunu yazars─▒n─▒z. S├╝r├╝mleriniz yeni nesnelere ayr─▒ bellek ay─▒r─▒r ve ilk i┼čaret├žinin adresini i┼čaret etti─či de─čerleri kopyalay─▒n.


151







Temel olarak bir y─▒k─▒c─▒n─▒z varsa (varsay─▒lan y─▒k─▒c─▒ de─čil), tan─▒mlad─▒─č─▒n─▒z s─▒n─▒f─▒n baz─▒ bellek ay─▒rmalar─▒na sahip oldu─ču anlam─▒na gelir. S─▒n─▒f─▒n baz─▒ m├╝┼čteri kodlar─▒ veya sizin taraf─▒n─▒zdan d─▒┼č─▒nda kullan─▒ld─▒─č─▒n─▒ varsayal─▒m.

     MyClass x(a, b);
    MyClass y(c, d);
    x = y; // This is a shallow copy if assignment operator is not provided
 

E─čer MyClass sadece ilkel bir yaz─▒l─▒ ├╝yeye sahipse, varsay─▒lan bir atama operat├Âr├╝ ├žal─▒┼č─▒r, ancak baz─▒ i┼čaret├ži ├╝yelerine ve atama operat├Ârlerine sahip olmayan nesneleri varsa, sonu├ž tahmin edilemez. Bu nedenle, bir s─▒n─▒f─▒n y─▒k─▒c─▒s─▒nda silinecek bir ┼čey varsa, derin bir kopya operat├Âr├╝ne ihtiya├ž duyabilece─čimizi s├Âyleyebiliriz, bu da bir kopya olu┼čturucu ve atama operat├Âr├╝ sa─člamam─▒z gerekti─či anlam─▒na gelir.


42







Bir nesneyi kopyalaman─▒n anlam─▒ nedir? Nesneleri kopyalaman─▒n birka├ž yolu vard─▒r - en ├žok at─▒fta bulunaca─č─▒n─▒z 2 t├╝rden bahsedelim - derin kopya ve s─▒─č kopya.

Nesne y├Ânelimli bir dilde oldu─čumuz i├žin (veya en az─▒ndan ├Âyle oldu─čunu varsay─▒yoruz), ayr─▒lan bir belle─činiz oldu─čunu varsayal─▒m. OO dili oldu─ču i├žin, tahsis etti─čimiz bellek par├žalar─▒na kolayca ba┼čvurabiliriz, ├ž├╝nk├╝ bunlar genellikle ilkel de─či┼čkenler (ints, chars, bytes) ya da kendi t├╝rlerimizden ve ilkellerden olu┼čan tan─▒mlanm─▒┼č s─▒n─▒flard─▒r. Diyelim ki ┼č├Âyle bir Car s─▒n─▒f─▒ var:

 class Car //A very simple class just to demonstrate what these definitions mean.
//It's pseudocode C++/Javaish, I assume strings do not need to be allocated.
{
private String sPrintColor;
private String sModel;
private String sMake;

public changePaint(String newColor)
{
   this.sPrintColor = newColor;
}

public Car(String model, String make, String color) //Constructor
{
   this.sPrintColor = color;
   this.sModel = model;
   this.sMake = make;
}

public ~Car() //Destructor
{
//Because we did not create any custom types, we aren't adding more code.
//Anytime your object goes out of scope / program collects garbage / etc. this guy gets called + all other related destructors.
//Since we did not use anything but strings, we have nothing additional to handle.
//The assumption is being made that the 3 strings will be handled by string's destructor and that it is being called automatically--if this were not the case you would need to do it here.
}

public Car(const Car &other) // Copy Constructor
{
   this.sPrintColor = other.sPrintColor;
   this.sModel = other.sModel;
   this.sMake = other.sMake;
}
public Car &operator =(const Car &other) // Assignment Operator
{
   if(this != &other)
   {
      this.sPrintColor = other.sPrintColor;
      this.sModel = other.sModel;
      this.sMake = other.sMake;
   }
   return *this;
}

}
 

Derin bir kopya, e─čer bir nesneyi bildirirsek ve o nesnenin tamamen ayr─▒ bir kopyas─▒n─▒ yarat─▒rsak ... 2 nesne ile 2 tamamen haf─▒za setine ula┼č─▒r─▒z.

 Car car1 = new Car("mustang", "ford", "red");
Car car2 = car1; //Call the copy constructor
car2.changePaint("green");
//car2 is now green but car1 is still red.
 

┼×imdi tuhaf bir ┼čey yapal─▒m. Diyelim ki araba2 yanl─▒┼č programlanm─▒┼č veya bilerek araba1'in yap─▒ld─▒─č─▒ ger├žek haf─▒zay─▒ payla┼čma ama├žl─▒. (Bunu yapmak genellikle bir hatad─▒r ve s─▒n─▒flarda genellikle alt─▒nda tart─▒┼č─▒lan bir battaniyelidir.) Car2 hakk─▒nda her ne zaman sorsan─▒z, ger├žekten car1'in haf─▒za alan─▒n─▒ g├Âsteren bir i┼čaret├ži ├ž├Âz├╝yorsunuz ... bu ne kadar az ne s─▒─č bir kopya oldu─čunu.

 //Shallow copy example
//Assume we're in C++ because it's standard behavior is to shallow copy objects if you do not have a constructor written for an operation.
//Now let's assume I do not have any code for the assignment or copy operations like I do above...with those now gone, C++ will use the default.

 Car car1 = new Car("ford", "mustang", "red"); 
 Car car2 = car1; 
 car2.changePaint("green");//car1 is also now green 
 delete car2;/*I get rid of my car which is also really your car...I told C++ to resolve 
 the address of where car2 exists and delete the memory...which is also
 the memory associated with your car.*/
 car1.changePaint("red");/*program will likely crash because this area is
 no longer allocated to the program.*/
 

Bu nedenle, hangi dilde yazd─▒─č─▒n─▒za bak─▒lmaks─▒z─▒n, ├žo─ču zaman derin bir kopya almak istedi─činizde, nesneleri kopyalarken ne demek istedi─činizi ├žok dikkatli olun.

Kopya kurucusu ve kopya atamas─▒ i┼čleci nedir? Onlar─▒ ├žoktan yukar─▒da kulland─▒m. Car car2 = car1; Bir de─či┼čken tan─▒mlay─▒p bir sat─▒ra atarsan─▒z, kopya kurucusu ├ža─čr─▒ld─▒─č─▒ zaman, Temel olarak gibi bir kod yazd─▒─č─▒n─▒zda kopya kurucu ├ža─čr─▒l─▒r. Atama operat├Âr├╝, e┼čittir i┼čareti kulland─▒─č─▒n─▒zda ger├žekle┼čen ┼čeydir car2 = car1; . Uyar─▒ car2 ayn─▒ beyanda belirtilmemi┼č. Bu i┼člemler i├žin yazd─▒─č─▒n─▒z iki kod par├žas─▒ ├žok benzer. Asl─▒nda, tipik tasar─▒m modelinin, ilk kopyalaman─▒n / ataman─▒n me┼čru oldu─čuna emin olduktan sonra her ┼čeyi ayarlamak i├žin ├ža─č─▒rd─▒─č─▒n─▒z ba┼čka bir i┼člevi vard─▒r - yazd─▒─č─▒m longhand koduna bakarsan─▒z, i┼člevler neredeyse ayn─▒d─▒r.

Onlar─▒ kendim ilan etmem ne zaman gerekir? E─čer payla┼č─▒lacak veya bir ┼čekilde ├╝retim i├žin kod yazm─▒yorsan─▒z, ger├žekten sadece ihtiyac─▒n─▒z oldu─čunda bunlar─▒ bildirmeniz gerekir. Program dilinizin 'kazayla' kullanmay─▒ se├žtiyseniz ve bir tane yapmad─▒ysan─▒z, yani derleyicinin varsay─▒lan─▒n─▒ ald─▒─č─▒n─▒zda ne yapt─▒─č─▒n─▒z─▒ bilmeniz gerekir. ├ľrne─čin nadiren kopya kurucular─▒ kullan─▒yorum, ancak atama operat├Âr├╝ ge├žersiz k─▒lmalar─▒ ├žok yayg─▒n. Toplama, ├ž─▒karma vb. ├ľ─čelerinin ne anlama geldi─čini ge├žersiz k─▒labilece─činizi biliyor muydunuz?

Nesnelerimin kopyalanmas─▒n─▒ nas─▒l ├Ânleyebilirim? ├ľzel bir i┼člevle nesneniz i├žin bellek ay─▒rman─▒za izin verilen t├╝m yollar─▒ ge├žersiz k─▒lmak makul bir ba┼člang─▒├žt─▒r. ─░nsanlar─▒n kopyalar─▒n─▒ ger├žekten istemiyorsan─▒z, herkese a├ž─▒k hale getirebilir ve bir istisna atarak ve ayr─▒ca nesneyi kopyalayarak programc─▒y─▒ uyarabilirsiniz.


35







Onlar─▒ kendim ilan etmem ne zaman gerekir?

├ť├ž Kural, herhangi birini a├ž─▒klarsan─▒z

  1. kopya kurucu
  2. kopya i┼čleci
  3. ├ž├Âp yakma f─▒r─▒n─▒

o zaman ├╝├ž├╝n├╝ de ilan etmelisin. Bir kopyalama i┼čleminin anlam─▒n─▒ devralma ihtiyac─▒n─▒n neredeyse her zaman bir t├╝r kaynak y├Ânetimi yapan s─▒n─▒ftan kaynakland─▒─č─▒ ve neredeyse her zaman bunun ima edildi─či sonucuna var─▒ld─▒.

  • Bir kopya i┼čleminde hangi kaynak y├Ânetimi yap─▒ld─▒ysa, muhtemelen di─čer kopya i┼člemlerinde yap─▒lmas─▒ gerekenler ve

  • S─▒n─▒f y─▒k─▒c─▒s─▒, kayna─č─▒n y├Ânetimine de kat─▒lacakt─▒ (genellikle serbest b─▒rakacak). Y├Ânetilmesi gereken klasik kaynak bellekti ve bu nedenle belle─či y├Âneten t├╝m Standart Kitapl─▒k s─▒n─▒flar─▒n─▒n (├Ârne─čin dinamik bellek y├Ânetimi yapan STL kapsay─▒c─▒lar─▒) hepsinin ÔÇťb├╝y├╝k ├╝├ž├╝ÔÇŁ: hem de kopyalama i┼člemleri ve bir y─▒k─▒c─▒ olarak ilan etmelerinin nedeni budur.

├ť├ž Kural─▒n─▒n bir sonucu, kullan─▒c─▒ taraf─▒ndan ilan edilen bir y─▒k─▒c─▒n─▒n bulunmas─▒n─▒n, basit ├╝ye bilgili kopyan─▒n s─▒n─▒ftaki kopyalama i┼člemleri i├žin uygun olma ihtimalinin d├╝┼č├╝k oldu─čunu g├Âstermesidir. Buna g├Âre, e─čer bir s─▒n─▒f y─▒k─▒c─▒ ilan ederse, kopyalama i┼člemlerinin muhtemelen otomatik olarak olu┼čturulmamas─▒ gerekti─či, ├ž├╝nk├╝ do─čru olan─▒ yapamad─▒klar─▒n─▒ g├Âstermektedir. C ++ 98'in kabul edildi─či zaman, bu ak─▒l y├╝r├╝tme s─▒ras─▒n─▒n ├Ânemi tam olarak anla┼č─▒lmam─▒┼čt─▒r, bu nedenle C ++ 98'de, bir kullan─▒c─▒n─▒n imha edici oldu─čunu beyan eden, derleyicilerin kopya i┼člemleri olu┼čturma iste─čini etkilememi┼čtir. C ++ 11'de durum b├Âyle olmaya devam ediyor, ancak yaln─▒zca kopya i┼člemlerinin ├╝retildi─či ko┼čullar─▒ k─▒s─▒tlamak ├žok eski kodlar─▒ k─▒raca─č─▒ndan.

Nesnelerimin kopyalanmas─▒n─▒ nas─▒l ├Ânleyebilirim?

Kopya yap─▒c─▒ ve kopya atama operat├Âr├╝n├╝ ├Âzel eri┼čim belirteci olarak bildirin.

 class MemoryBlock
{
public:

//code here

private:
MemoryBlock(const MemoryBlock& other)
{
   cout<<"copy constructor"<<endl;
}

// Copy assignment operator.
MemoryBlock& operator=(const MemoryBlock& other)
{
 return *this;
}
};

int main()
{
   MemoryBlock a;
   MemoryBlock b(a);
}
 

Ayr─▒ca C ++ 11'de kopya yap─▒c─▒ ve atama operat├Âr├╝n├╝n silindi─čini beyan edebilirsiniz.

 class MemoryBlock
{
public:
MemoryBlock(const MemoryBlock& other) = delete

// Copy assignment operator.
MemoryBlock& operator=(const MemoryBlock& other) =delete
};


int main()
{
   MemoryBlock a;
   MemoryBlock b(a);
}
 

24







Mevcut cevaplar─▒n ├žo─ču zaten kopya kurucuya, atama operat├Âr├╝ne ve y─▒k─▒c─▒ya dokunuyor. Ancak, C ++ 11 sonras─▒, semantik hareket tan─▒t─▒m─▒ bu 3 ├Âtesine geni┼čletebilir.

Son zamanlarda Michael Claisse bu konuya de─činen bir konu┼čma yapt─▒: http://channel9.msdn.com/events/CPP/C-PP-Con-2014/The-Canonical-Class


14


2015-01-07





C ++ 'daki ├╝├ž├╝n kural─▒, a┼ča─č─▒daki ├╝ye fonksiyonlar─▒ndan birinde net bir tan─▒m varsa, programc─▒n─▒n di─čer iki ├╝ye fonksiyonunu birlikte tan─▒mlamas─▒ gereken ├╝├ž ┼čart─▒n tasar─▒m ve temel ┼čartlar─▒n geli┼čtirilmesi ilkesidir. Yani a┼ča─č─▒daki ├╝├ž ├╝ye i┼člevi vazge├žilmezdir: y─▒k─▒c─▒, kopya kurucu, kopya atama operat├Âr├╝.

C ++ 'da kopya kurucu ├Âzel bir kurucu. Mevcut bir nesnenin kopyas─▒na e┼čde─čer olan yeni nesne olan yeni bir nesne olu┼čturmak i├žin kullan─▒l─▒r.

Kopyalama atamas─▒ i┼čleci, genellikle ayn─▒ nesne t├╝r├╝n├╝n ba┼čkalar─▒na varolan bir nesneyi belirtmek i├žin kullan─▒lan ├Âzel bir atama i┼člecidir.

H─▒zl─▒ ├Ârnekler var:

 // default constructor
My_Class a;

// copy constructor
My_Class b(a);

// copy constructor
My_Class c = a;

// copy assignment operator
b = a;
 

9



─░lgili yay─▒nlar


Std :: make_pair'─▒n std :: pair yap─▒c─▒s─▒na kar┼č─▒ amac─▒ nedir?

Android s─▒n─▒f BaseAdapter'da getItem ve getItemId y├Ântemlerinin amac─▒ nedir?

Metot isimlerinin sonunda ÔÇť!ÔÇŁ Ve ÔÇť?ÔÇŁ Nin amac─▒ nedir?

Birle┼čtirme i┼člecinin bir Vekt├Âr dizesi ├╝zerindeki kar┼č─▒l─▒─č─▒ nedir?

D├Âng├╝ sonunda ÔÇť;ÔÇŁ nin amac─▒ nedir?

Log4j.rootLogger ├Âzelli─činin log4j.properties dosyas─▒ndaki ├Ânemi nedir? Bu ├Âzelli─či kullanmazsam ne olur?

GlBindVertexArrays ve glBindBuffer'in rol├╝ nedir ve ili┼čkileri nedir?

@Id ve @GeneratedValue ek a├ž─▒klamalar─▒n─▒n kullan─▒m─▒ nedir (strategy = GenerationType.IDENTITY)? Generationtype neden kimliktir?

Yeni bask─▒ i┼člevinin Python 3.x'deki Python 2 print deyimine g├Âre avantaj─▒ nedir?

.Exp kullan─▒m─▒ ve .lib ve .dll aras─▒ndaki fark nedir?

Etiketle ilgili di─čer sorular [c++]


JavaScriptÔÇÖte bo┼č, tan─▒ms─▒z veya bo┼č de─či┼čkenleri kontrol etmek i├žin standart bir i┼člev var m─▒?

Bir dize ba┼čka bir dize ÔÇťba┼člarÔÇŁ ile nas─▒l kontrol edilir?

Bir nesne ad─▒ndan ├Ânceki tek ve ├žift alt ├žizgi anlam─▒ nedir?

Varsa bir tablo nas─▒l a├ž─▒l─▒r?

D├╝z ─░ngilizce olarak, ÔÇťgit resetÔÇŁ ne yapar?

PDO haz─▒rlanm─▒┼č ifadeler SQL enjeksiyonunu ├Ânlemek i├žin yeterli mi?

Nas─▒l d├╝zeltilir: ÔÇťPageHandlerFactory-IntegratedÔÇŁ i┼čleyicisi mod├╝l listesinde k├Ât├╝ bir ÔÇťManagedPipelineHandlerÔÇŁ mod├╝l├╝ne sahip

Android'de bir ImageView URL ile nas─▒l y├╝klenir? [kapal─▒]

Objective-C'de soyut bir s─▒n─▒f olu┼čturma

Reinterpret_cast ne zaman kullan─▒l─▒r?