2011-12-22 37 views
5

Ben dinamik bir dizi uygulamaya çalışıyorum: Böyle kullanıldığında, beklendiği işleri gibiİki Boyutlu Dizi kullanarak şablonlar

template <typename Item> 
class Array { 
private: 
    Item *_array; 
    int _size; 
public: 
    Array(); 
    Array(int size); 
    Item& operator[](int index); 
}; 

template <typename Item> 
Array<Item>::Array() { 
    Array(5); 
} 

template <typename Item> 
Array<Item>::Array(int size) { 
    _size = size; 
    _array = new Item [size]; 

    for (int i = 0; i < size; i++) 
     cout << i << " " << _array[i] << " " << &_array[i] << endl; 
} 

template <class Item> 
Item& Array<Item>::operator[](int index) { 
    if (index < 0 || index > _size-1) 
     cout << "this: " << this << ". Index out of range" << endl; 

    return _array[index]; 
} 

yani baskılar 5: Ancak

Array<int> testArray(5); 
testArray[0] = 5; 
cout << testArray[0] << endl; 

, isterim İki boyutlu bir dinamik dizi için sınıf kullanmayı sever. Ben şu sihirli bir çalışma ve baskı 5 ...

Array< Array<int> > testArray(5); 
testArray[0][0] = 5; 
cout << testArray[0][0] << endl; 

... ama çalışmıyor düşündüm. [0] [0] 'da değeri ayarlamaya çalıştığımda çöküyor. Hata ayıklayıcı, this'un _size'un 0 ve _array'a NULL olarak ayarlandığını gösterir. Bu noktada this, son oluşturulan Array örneğinin _array öğesinin ilk öğesini işaret eder.

"İç" dizinin yapıcısını çağırması, elde edemediğim şeylerden biri. Kodun içine adım attığımda, Array(int size)'un bir kez ve Array() beş kez çağrıldığını görüyorum. İç diziyi belirli bir boyutta oluşturmak istiyorum, ancak Array< Array<int>(10) > testArray(5)'u kullanarak derleme yapmıyor.

Bu konuda bana biraz bilgi verebilir misiniz? Görünüşe göre kafamı henüz şablonların etrafına dolamıyordum ...

cevap

6

Kurucu aramalarını C++ 'da zincirleyemezsiniz. İlk kurucu uygulamanızın hiçbir şey yapmadığı için, Array numaralı ana öğede bulunan 5 durumun başlatılmamış olmasıyla sonuçlanır, bu da tanımlanmamış bir davranışla sonuçlanır. Düzeltmek için, diğer kurucunun size parametresine bir varsayılan değer ekleyebilir veya başlatma mantığını ayrı (özel) bir işleve dahil edebilir ve her iki kurucudan da çağırabilirsiniz.

DÜZENLEME: İlk kurucu hiçbir şey yapmaz nedeni budur hat

Array(5) 

akım örneğinin kurucusunu çağırmak, ancak bunun yerine yeni bir (adsız) geçici Array örneği ayırır gelmediğini hangi Hattın sonunda derhal imha edilir. Yapıcı argüman olmadan çağırmak için

+0

Oh, Kurucu aramalarını zincirleyemediğini bilmiyordum! Şimdi özel bir işlev oluşturdum ve şimdi çalışıyor, ancak yalnızca varsayılan kurucuda belirtilen boyutta çalışıyor. İçsel diziyi dinamik boyutta oluşturma hakkında herhangi bir fikir var mı? – fabian789

+0

C++ 11 ** ve ** kullanıyorsanız, dış dizi boyutu statik olarak bilinir, tüm iç diziler için başlatıcılar sağlamak üzere bir başlatıcı listesi kullanabilirsiniz. Her neyse, cevabımda bunu yazmayı unuttum, ama bu bir egzersizden başka bir şey olmadıkça, gerçek çözüm 'std :: vector' kullanmaktır. –

+0

Evet, sadece bir alıştırma. "Başlatıcı listesi" ile ne demek istediğini söyler misin? '_array = new Item [size] kullanarak (boyut);' benim için derleme yapmıyor. – fabian789

1

Varsayılan ctorunuzdan başka bir ctor'u arayamazsınız. Varsayılan bir değere sahip olmak istiyorsanız, ikisini bir araya getirebilirsiniz.

template <typename Item> 
Array<Item>::Array(int size = 5) { 
    _size = size; 
    _array = new Item [size]; 

    for (int i = 0; i < size; i++) 
     cout << i << " " << _array[i] << " " << &_array[i] << endl; 
} 

Ancak yine de o zaman böyle hem kullanılabilecek özel _setup işlevine uygulanmasını taşıyabilirsiniz iki ctor olmasını tercih eğer.

template <typename Item> 
Array<Item>::Array() { 
    _setup(5); 
} 

template <typename Item> 
Array<Item>::Array(int size) { 
    _setup(size); 
} 

template <typename Item> 
void Array<Item>::_setup(int size) { 
    _size = size; 
    _array = new Item [size]; 

    for (int i = 0; i < size; i++) 
     cout << i << " " << _array[i] << " " << &_array[i] << endl; 
} 

Düzenlenmiş

Yenilenmistir dizi için geçersiz başlatıcı kaldırın.

+0

[] parantezleri benim için derleme yaptıktan sonra (boyut) ekleniyor ...? – fabian789

+0

Bu yüzden kendimden daha önce geldiğimi ve yeni deyim ile diziler için bir başlatıcı belirleyemeyeceğinizi unuttum. Belki bir diziye işaretçi yerine bir vektör kullanmak ideal olacaktır. Eğer sınıf için varsa ve herhangi bir mevcut stl kullanamazsınız şüpheleniyorum. – jbreiding

+0

Evet, sadece bir egzersiz :) – fabian789