2016-04-14 17 views
-1

Kopya oluşturucuları nasıl arayacağımı/oluşturduğumu anlama konusunda sorun yaşıyorum. Sorunum bunu ana olarak nasıl aramaya çalıştığım arasında mı yatıyor? Ya da bunun Animal.cpp'de yapılması gereken belirli bir yol var mı?Kopya Oluşturucuları nasıl doğru şekilde kullanırsınız?

Çalışıyor olsaydı, temel sınıf olarak Animal kullanılarak türetilmiş sınıfları olan bir kopya oluşturucuyu çağırır mıyım?

Animal::Animal(const string &s, const string &c,const string &a, const string &d) 
    : species(s), classification(c), animal(a), desc(d) 
{ 
} 

da const-referansla açık geçiş not: mümkünse

Animal.cpp

#include "Animal.h" 

using namespace std; 

Animal::Animal() 
{ 

} 

Animal::Animal(string s, string c,string a, string d) 
{ 
    species = s; 
    classification = c; 
    animal = a; 
    desc = d; 

} 

Animal::Animal(const Animal &obj) 
{ 
    //What should be placed in here? 
} 

main.cpp

#include <string> 
#include <iostream> 
#include "Animal.h" 


using namespace std; 

int main(){ 



    Animal *elephant = new Animal("Straight-Tusked","Mammal","Elephant","Grazer"); 

    Animal *elephant2 = new Animal(*elephant); 

} 
+1

Başka bir 'Hayvan' ile' Hayvan'ı nasıl oluşturacağınızı tanımlamanız gerekir. Değerleri kopyalayabilir misin? –

+3

Sorunuzla ilgisi yok, fakat Java veya C# arka planından mı geliyorsunuz? Çünkü C++ 'da yeni nesneler yaratmak için 'new' kullanmanız gerekmiyor. Ör. 'Hayvan fil (...);' Tamamen iyi. Ve sonra basitçe 'Animal elephat2 = elephant' yapabilir ve kopya-kurucu çağrılır. –

+0

Lütfen "Animal" sınıfının beyanını gösterin, ya da biz söyleyemeyiz. – MikeCAT

cevap

3

C++, her zaman üye initalizers kullanımı . string s'u iletirseniz, parametrenin örtülü bir kopyasını alırsınız. Derleyici muhtemelen copy-elides, bu yüzden bir fark görmeyeceksiniz, ancak seçim, olabilecek veya olmayabilecek bir optimizasyon. Kopya yapıcı *this için uygun değerler atayarak obj bir kopyasını yapmalıdır

Animal::Animal(const Animal &obj) 
    : species(obj.species) 
    , classification(obj.classification) 
    , animal(obj.animal) 
    , desc(obj.description) 
{ 
} 

: kopya kurucu gelince

, biz Animal sınıftan gördükleri giden, muhtemelen böyle bir şey istiyorum . Yukarıdakilerin, varsayılan, otomatik oluşturulmuş kopya oluşturucunun yaptığı da (başka alan yoksa) olduğunu unutmayın.

yukarıda açıkça default copy constructor oluşturmak için C++ 11 ve üzeri, sen derleyici söyleyebilir içinde, aslında varsayılan kopya kurucu aynıdır Çünkü: rule-of-three tarafından itibariyle

class Animal { 
    Animal(const Animal &) = default; 
}; 

(rule- günümüzde beşi), muhtemelen bir kopya atanan operatör de istersiniz.

Son olarak, new bir yere sahip olduğunuzda, nesneyi delete gerekir. C++ (yerleşik) referans sayımı yapmaz ve bir çöp toplayıcısına sahip değildir. delete a new d nesnesini unutursanız, bir bellek sızıntınız olur.

açıklamalarda belirtildiği gibi

, sadece bir değişken

Bu otomatik olarak temizlenecek (ve yıkıcı adlı)
Animal a(
    "Hippopotamus", 
    "Mammalia", 
    "Hippopotamus", 
    "from the movie" 
); 

zaman programı yaprakları ilan ederek bir Animal nesneyi ilan etmek, ancak, tamamen mümkündür Mevcut kapsam. Kabul edilen bir cevabı olmamasına rağmen

+0

Bu davranış varsayılan olduğundan, Animal (const Animal &) = default; 'seçeneğini bildirme seçeneğinden bahsetmeyi düşünürdüm. – Zereges

+0

@Zereges ... C++ 11 ve üstü ;-) kullanılıyorsa. Ve evet, ekledi. – dhke

+0

"Üçüncüsü", "sıfır kuralı" dır ... herşeyin varsayılan olarak üretilen sürümleri doğrudur, yani daha azı daha iyi –

1

, ben bir kopyası yapıcı o isim olarak tanımlıyor tam olarak ne olduğunu Kodunuzdaki

//What should be placed in here? 

açıklamanızı ele düşündüm. Aynı türden başka bir nesneden bir nesne oluşturan bir işlevdir. Bu nedenle kısa cevap, bir kopya oluşturucusuna gider, varolan bir örneği yapım kaynağı olarak kullanarak yeni bir nesne örneği oluşturan koddur.

Derleyici, kendiniz tedarik etmiyorsanız bir kopya oluşturucu oluşturur. Derleyicinin kopya kurucusunda, örnek 'bitwise kopyalanmıştır', yani sınıfın tüm veri üyeleri bit için kopyalanır.

Veri üyelerinizden biri veya daha fazlası işaretçilerse bu bir sorun oluşturabilir. Bir bit kopyada, kopya örneğinin işaretçileri, kopyalandığı nesne ile aynı nesnelere işaret eder. Nesne kopyalandığında, işaret ettiği nesneleri oluşturmayı kopyalamak isteyebilirsiniz. Bu kendi kopya kurucunuzu tedarik etmenin nedenlerinden biridir. Örneğin

:

class Foo 
{ 
public: 
    int a; 
    int b; 

    Foo() : a(0), b(0) {} 
    Foo(int ain, int bin) : a(ain), b(bin) {} 
    ~Foo() {} 
} 
class Bar 
{ 
    double z; 
    Foo* foo; 
public: 
    Bar() : z(0) , foo(new Foo) {} 
    Bar(double zin, Foo* fooin) : z(zin), foo(fooin) {} 
    // Copy constructor below 
    Bar(const Bar &rhs) : z(rhs.z) , foo(new Foo(rhs.foo->a, rhs.foo->b)) {} 
} 

Bar'ın kopya yapıcı da buna yeni bir Foo nesne ve nokta inşa edecek. Bar'ın kopya yapıcı da böyle yapılabilir Not:

Bar(const Bar &rhs) : z(rhs.z) , foo(new Foo((const Foo&)*(rhs.foo))) {} 

Foo için derleyici'nın varsayılan kopya kurucu kullanacaktır. üye ilklendiriciler tercih edilirken

, bu kurucular fonksiyonlarını olduğunu hatırlamak yararlıdır, yani bu şöyle işaretçi kullanarak kopya kurucu gelen başka yapıcısı çağırabilir: Aşağıdaki olduğunu

Animal::Animal(const Animal &obj) 
{ 
    this->Animal(obj.s, obj.c, obj.a, obj.d); 
} 

Not çalışmaz:

Animal::Animal(const Animal &obj) 
{ 
    Animal(obj.s, obj.c, obj.a, obj.d); 
} 

o (en azından zaten benim derleyici üzerinde) kurucusuna bir işlev çağrısı ifadesi olarak ele alınır ve anonim nesne oluşturmak ve edilmeyecektir çünkü.

İlgili konular