2012-02-21 23 views
5

Bir metin dosyasına, kendisine gönderilen verileri kaydeder bir işlevi bulunan bir sınıf yapmak istiyorum. kendisine geçirilen edilebilir veri vb std::string, int, double, float, unsigned int, böyle bir şey olabilir ve aynı zamanda bir olabilir: std::vector<T>, T[] ve std::vector<std::vector<T>>, T[][]. o diziyseC++ tipleri inşa diziler, vektörler, için şablon işlevi, STL

Şimdi, belli ki, ben metin dosyası veri göndermek içinden yineleme gerekecektir.

Ben şablonları kullanarak düşünüyordum ama diziler nasıl emin değilim.

bu yöntem midir?

class CMyClass 
{ 
    template<typename T> 
    void SaveData(T data); 
    void SaveData(std::vector<T> data); 
    void SaveData(std::string data); 
    void SaveData(T* data);    // Perhaps I'll also need to pass in the size. 
    void SaveData(std::vector<std::vector<T>> data); 
    void SaveData(T** data); 
}; 

Ben std::string için kod std::vector<T>T bir (int veya float falan bir benzeri) tipinde inşa olması şartıyla için koduyla aynı olacağını düşünün.

Sonra buna göre SaveData(...) her biri için işlevler yazmak? Bildiğim kadarıyla gördüğünüz gibi, sınıf ne hakkında (onun "sorumluluk") bir dosyaya veri yazmaktır:

+0

Başlığınız çok geniş ve belirsiz, bunu yeniden ifade etmek isteyebilirsiniz. –

+4

FYI: http://www.boost.org/doc/libs/1_48_0/libs/serialization/doc/index.html – Anycorn

cevap

5

İlk olarak, sınıf veya işlevlerini şablon ya. Diziler de yapmak istediğiniz için, numaralı telefonun numaralı telefonu kullanmanız gerekir.Örnek aşağıdaki gibidir:

int i; 
int i1[5]; 
int i2[5][7]; 
std::vector<int> v1; 
std::vector<std::vector<int> > v2; 
std::string s; 

CMyClass saveClass; 

saveClass.SaveData<int>(i); 
saveClass.SaveData<int>(i1); 
saveClass.SaveData<int>(i2); 
saveClass.SaveData<int>(v1); 
saveClass.SaveData<int>(v2); 
saveClass.SaveData(s); 

İhtiyaca göre, sınıf bir tekil yapabilir ve işlevleri statik: Eğer işlevleri tanımladıktan sonra

class CMyClass 
{ 
public: 
    template<typename T> void SaveData(const T &data); 
    template<typename T, size_t N> void SaveData(const T (&data)[N]); 
    template<typename T, size_t N, size_t M> void SaveData(const T (&data)[N][M]); 
    template<typename T> void SaveData(const std::vector<T> &data); 
    template<typename T> void SaveData(const std::vector<std::vector<T> > &data); 
    void SaveData(const std::string &data); 
}; 

, aşağıdaki örnekte Onları arar nasıl gösterir , işlevlerini hiç CMyClass örneğini ihtiyacını atlayarak ve basitçe çağıran şöyle:

CMyClass::SaveData<int>(i); 
CMyClass::SaveData<int>(i1); 
CMyClass::SaveData<int>(i2); 
CMyClass::SaveData<int>(v1); 
CMyClass::SaveData<int>(v2); 
CMyClass::SaveData(s); 

Notlar:

  1. Argümanlar ayrıca referanslar olmalıdır (ör. "Veri" yerine "& veri", böylece işlevi çağırdığınız her seferinde tüm kabın bir kopyasını yapmak yerine yalnızca referans alınır.
  2. Tüm sınıfın bunun bir başka sınıf tarafından erişileceğini ve işlevlerinin tümüyle erişilebilir olduğunu varsayarak, işlevleri açık olarak açıkça beyan ettim. Varsayılan olarak, bir sınıfın üyeleri özeldir.
  3. İç içe geçmiş her ">" arasında boşluk olduğundan emin olun.

İyi şanslar!

+0

Teşekkür ederim! Bu gerçekten yardımcı olur. Yine de bir sorum var, neden veri yerine kelime dizisini kullandınız? Bu sadece bir isimlendirme meselesi mi, yoksa ... bir şey mi yapıyor, çünkü sadece VS'de bir şeyler yapmamı okudum. –

+0

Değişken adı olarak "dizi" kullanmam sadece bir alışkanlık gücüydi. Kodu düzenledim, böylece arayüz tutarlılığını korumak için artık "veri". Endişelenme, "dizi" C++ 'da bir anahtar kelime değildir. Ortaya çıkabilecek herhangi bir karışıklık için üzgünüm! – athwaites

+0

std :: vector > uygulamak için son bir soru, ben tekrar bir ayrı aşırı yük yapmak zorunda, bir son soru, teşekkür ederim, bu yöntemin std :: vektör >? –

0

Sana kaçınılması gereken bir sınıfta, iki şey karıştırma inanıyorum. Eklemekte olduğunuz başka bir şey, veri koleksiyonlarını yinelemek hakkında bilgi. Eğer ilerlerken verilerin, örneğin jenerik yollarını bulabilirsiniz Orada

http://www.cplusplus.com/reference/algorithm/

:

STL? <algorithm> yöntemlere bir göz atın find yöntemde:

template<class InputIterator, class T> 
    InputIterator find (InputIterator first, InputIterator last, const T& value) 
    { 
    for (;first!=last; first++) if (*first==value) break; 
    return first; 
    } 

Bu vector, list, diziler ya da her neyse kullanıp kullanmadığınızı dan sizi özgür kılar.

ayrıca vector<vector<T> > gibi şeyler seri hale getirmek istiyorsanız

(iki > arasındaki boşluğu dikkat!), Size böyle verilerle yapmak istediklerinize daha fazla açıklamak zorunda. Tüm T s'nin bir vector sürümünde olduğu gibi öğeleri basitçe dağıtın? Bu durumda, tam olarak bunu yapan yeni bir yineleyici oluşturmaya çalışabilirsiniz. yineleyici kütüphanesi bu konuda yardım olabilir

boost:

http://www.boost.org/doc/libs/1_48_0/libs/iterator/doc/index.html

+0

Öneriniz için teşekkürler. Detaylandırmak için, bu şekilde bir metin dosyasına ne yazıldığını yazmak istiyorum: ifstream ifs ("test.txt", ifstream :: in); ifs << veri. Eğer veri bir vektör ise, o zaman veriyi bir int ise, üzerinde durmak zorundayım, o zaman ben yok. Eğer veri bir T [] [] ise, ben de bunu tekrarlamak zorundayım ... std :: algoritmasının ve for_each (...) gibi fonksiyonların farkındayım. Ancak, kullanıcının bir int veya char içinde geçmesi durumunda nasıl yardımcı olacağını görmüyorum. Ayrıca, std :: for_each std :: vector > gibi şeyler kullanabileceğime de inanmıyorum. –