Tam Sürümünü Görmek İçin : Dosyaya nesneler yardımıyla yazma
Arkantos
29/03/2004, 20:19
Şimdi elimde nesneler yardımıyla dosyaya yazmak için basit bir kod var:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Ogrenci
{
short numara;
char adi[20];
public:
void VeriAl()
{
cout << "Numarasi: ";
cin >> numara;
cout << "Adi: ";
cin >> adi;
}
};
int main()
{
Ogrenci ogr;
ogr.VeriAl();
ofstream dosya("deneme.txt", ios::binary);
dosya.write((char*) &ogr, sizeof(ogr));
return 0;
}
Bu kod ikili olarak bir dosyaya kullanıcının girdiği verileri yazıyor. Şimdi ben bunu daha nesnesel bir hale getirmek için kodu şu şekilde değiştirdim.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Ogrenci
{
short numara;
char adi[20];
public:
void VeriAl()
{
cout << "Numarasi: ";
cin >> numara;
cout << "Adi: ";
cin >> adi;
}
void VeriGoster()
{
cout << "Numarasi: " << numara << endl;
cout << "Adi: " << adi << endl;
}
void VeriOku(Ogrenci *g)
{
ifstream dosya1("deneme.txt", ios::binary);
// dosya1.read((char*)(&(*g), sizeof(*g));
// Yukarıdaki gibi kullanmayıp bu şekilde kullanım doğru olur mu?
dosya1.read((char *) g, sizeof(*g));
dosya1.close();
}
void VeriYaz(Ogrenci *g)
{
ofstream dosya("deneme.txt", ios::binary);
// dosya.write((char*)(&(*g)), sizeof(*g));
// Yukarıdaki gibi kullanmayıp bu şekilde kullanım doğru olur mu?
dosya.write((char *) g, sizeof(*g));
dosya.close();
}
};
int main()
{
Ogrenci ogr;
Ogrenci *g; // Burada öğrenci nesnesi için bir gösterge tanımladım.
g = &ogr; // Göstergeye nesnenin adresini atadım.
ogr.VeriAl();
ogr.VeriYaz(g); // Veriyaz fonksiyonuna göstergeyi referans olarak geçtim.
ogr.VeriOku(g); // Aynı şekilde veriyi okuyorum.
ogr.VeriGoster();// Bilgileri gösteriyoruz
return 0;
}
Şimdi benim sormak istediğim dosya1.read .. kısmında bu şekilde bir kullanım doğru olur mu? Yoksa açıklama haline getirilmiş şekilde mi kullanmalıyım? Burada dosya.read(..) kısmındaki char* tip dönüştürme işlemi mi yapıyor? (type cast) Bir diğer sorum bu yazdığım nesne nesnesel yaklaşımla uygun bir sınıf olmuş mu? Olmamışsa önerileriniz..
acehreli
29/03/2004, 23:40
Arkantos, her iki program icin de, <string> basligini ekledigin halde std::string'den yararlanmamis olmak yanlis. Ad icin 20'den fazla karakter geldiginde bu program dogru calismayacaktir. :)
Ote yandan string kullandigin zaman da, (char *) ve sizeof marifetiyle yaptigimiz sihir ise yaramayactir :) Cunku string'in karakterlerini tuttugu bellek dinamik olarak ayrilmis ve yalnizca string'in bildigi bir yerdedir.
Tabii string bu yontemin calismamasi konusunda yalnizca bir ornektir... Yapinin (veya sinifin) bellekteki halini ancak cok kisitli durumlarda boyle yazdirip okuyabilirsin. Ayrica sayilarin karakter karsiliklarinin kullanilan islemciye gore degismesi de cabasi (big/little endian sorunlari). Kisacasi, read ve write yontemiyle yaptigin okuma ve yazma genelde yanlistir.
Nesneleri kullanilir hale getirmek icin VeriAl gibi islevler yazmak yerine, kurucu islevler tanimlayabiliriz (buradaki kodlarda hatalar olabilir; derlemeden yaziyorum):
class Ogrenci
{
/* ... */
public:
Ogrenci(short numara, string const & adi);
/* ... */
};
Boylece ortalikta gecersiz Ogrenci kalmamis olur. Ogrencileri, daha ust duzey bir kod olusturabilir:
Ogrenci ogrenciOku(istream & giris)
{
short numara;
giris >> numara;
string adi;
giris >> adi;
return Ogrenci(numara, adi);
}
Baska bir yol, ogrencilerin "bos" olmalarini kabul ederek, senin yaptigin gibi VeriAl islevini tanimlamak, ama onu gelenek oldugu gibi operator>> olarak adlandirmaktir:
class Ogrenci
{
friend istream & operator>> (istream & giris, Ogrenci const &);
/* ... */
};
istream & operator>> (istream & giris, Ogrenci const & ogrenci)
{
ogrenci = ogrenciOku(giris);
return giris;
}
int main()
{
Ogrenci ogrenci;
/* ... */
/* 'giris' burada tanimlanmis bir giris akimi olsun */
giris >> ogrenci;
}
Ogrenciyi yazdirma isi de geleneksel olarak operator<< isleciyle yaptirilabilir:
ostream & operator<< (ostream & cikis, Ogrenci const & ogrenci)
{
return cikis << "Numarasi: " << numara << '\n'
<< "Adi: " << adi << '\n';
}
Bunlarin disinda, endl kullanimi konusunda da supheliyim. Cikis akiminin hizli calismak amaciyla tuttugu ara bellegi gercekten hemen yazdirmak istiyor muyuz? Ben oyle olduguna inanmadigim icin yukarida '\n' karakterleri kullandim. Cunku endl, cikisa once bir '\n' sonra da bir 'flush' gonderir:
cout << endl;
cout << '\n' << flush; // usttekinin esdegeri
Ali
Arkantos
30/03/2004, 11:36
Tam ilk C++ kitabımı bitirmek üzere olmanın (son konu Standart Şablon Kütüphanesi kalmıştı) gönül rahatlığıyla yeni bir kitaba geçecekken birden şok oldum diyebilirim. :2:
Sizin bu yazdığınız kod (sizde okumuşsunuzdur) B.S'a "Niçin Merhaba Dünya programı için C++ ile yazdığım kod C ile yazdığım kodun 10 katı büyüklüğünde?
gibisinden bir soru soruluyor. O da yanıt olarak bu sizin bilgisayarınızda olabilir. Aslında benim bilgisayarımda aynı programın C++ ile yazılmış nesnesel kodu C ile yazılmış olandan daha az yer kaplıyor..." gibi bir cevap veriyor. Bunu hatırlattı :) Ve böylece Nesne Yönelimli Yaklaşımı es geçtiğimi gördüm. İlk olarak yanlışı C++ öğrenmeye başlarken direkt olarak Managed C++ öğrenmeye başlamak ile yaptım sanırım. Yaklaşık olarak 5 ayda falan kabaca Windows kontrollerine kadar geçtim. Ve bunları tam anlamıyla kavramam için C++ öğrenmem gerektiğini farkederek yaklaşık bir 5 aydır falan da C++ öğrenmeye çalışıyorum. Şu an incelediğim C++ ile ilgili kitabın aslında NYP tekniğini anlatmak konusunda eksik kaldığını ben de farketmiştim. Örneğin soyutlama. Mesela bu sadece kavram olarak verilmiş. Yani bu pratik olarak kod yazarken hangi durumlarda gereklidir, nasıl kullanılmalıdır ve bunu kullananan gerçek bir uygulama nasıl olmalıdır gibisinden şeyler eksik kalıyordu. Diğer kitabın yazarı (Julian Templeman - Adım Adım Microsoft Visual C++.NET) aslında Managed C++ anlatılmasına rağmen bence bu kavramları daha iyi özümsemiş. Aslında şu an okuduğum kitapta konuları oldukça sade bir biçimde anlatmış. Ama dediğim gibi belirli konularda eksiklikler var. Yine de C++'ye yeni başlayanları temel kavramlarla tanıştırma açısından ben şahsen hiç programlama ya da C++ bilgisi olmayan insanlara bu kitabı tavsiye ederim.
Sonuç olarak kendime C++ öğrenirken bir yol haritası çizmeye karar verdim ve bunu yaparken de sizin gibi tecrübeli insanlardan yardım almaya karar verdim.
Bir de internette gezerken şöyle bir şey buldum :)
Ali has been working in Silicon Valley as a software engineer in the ...
Bu sizmisiniz? Eğer bu sizseniz kendi adıma çok gurur duyduğumu söyleyebilirim.
Yine internette gezerken şöyle bir şey buldum.
C++ C'den bagimsiz bir dildir. C++ ile program yazip kullanabilmek icin C bilmeye gerek yoktur.
1) C++'i verimli kullanabilmek icin C++'ca dusunmek gerekir.
2) C++ C'de *** yapilan yanlislari onler.
3) Ancak C++'ta ilerledikce ve gerektikce C'yi ogrenmeye gecilmelidir.
Bjarne Stroustrup bu fikirleri bir yazisinda anlatmaya calisiyor. Ben Turkce cevirisini
http://home.attbi.com/~ali.cehreli/turkcecpp/cpp_ogrenmek.html
adresine koydum. Bence oradaki ornekler cok carpici.
Sanırım bunlar da size ait. Benim sormak istediğim C++ öğrenirken tavsiye edebileceğiniz Türkçe kitap var mı? (en az iki tane) Şu an okuduğum kitabı bitirdikten sonra Bora Güngören Nesneye Yönelik Programlama kitabına geçmeye düşünüyorum.(İncelediğim kadarıyla NYP tekniği olarak daha fazla örnek ve anlatım var gibi) Ne dersiniz? İngilizceyi hala öğreniyorum.(Giriş Seviyesi) Bu kitapları okuduktan sonra tavsiye edebileceğiniz C++ ile ilgili yabancı kitap var mı? ( Özellikle bir kaç tane Türkçe kitap tavsiye edebilirseniz sevinirim.Çeviri de olabilir) Yukardaki bağlantı sanırım çalışmıyor. Bu tür C++ ile ilgili kaynakları siteye atabilirmisiniz ? Son olarak da bir öneri programlama bölümündeki C ve C++ bölümünü ayırabilirmisiniz?
Not : Hala yazdığınız sınıfı anlamaya çalışıyorum. Tam anlamıyla anladıktan sonra 1-2 soru gelebilir :)
Erdem
acehreli
30/03/2004, 21:03
Erdem, sana oncelikle iyi sanslar ve basarilar. Su anda fazla zamanim olmadigi icin uzun yazamiyorum ama hic olmazsa o baglantinin dogrusunu yazayim:
http://home.comcast.net/~ali.cehreli/turkcecpp/cpp_ogrenmek.html
attbi.com bir sene kadar once comcast.net olarak degistigi icin baglanti bozulmus. O sayfadaki mektup adresim de ayni nedenden bozuk: artik attbi.com diye bir sey yok :)
Ali
Arkantos
30/03/2004, 22:12
Teşekkürler :)
acehreli
31/03/2004, 22:02
Erdem,
Son konudan anladigim kadariyla Herbert Schildt'in kitabinin Turkce'sini okuyorsun. Benim bildigim en iyi Turkce kitap da o. Bora Gungoren'in 'C++ ile Nesne Tabanli Programlama' kitabi bence Schildt'inki kadar iyi degil. Yine de degisik kaynaklari okumak bence cok yararlidir.
Bu kitaplarin elestirilerini su adreslerde bulabilirsiniz:
http://groups.yahoo.com/group/cdili/message/1769
http://groups.yahoo.com/group/cdili/message/1678
Aslinda daha onceki olumsuz elestirilerim icin genelde biraz sucluluk duyuyorum. Ne olursa olsun, Turkce kitaplari desteklememiz gerekir.
O elestirilerin yazildigi cdili grubunun arsivlerinde 'Kitap elestirisi' diye aratarak baska elestilir de bulabilirsiniz. Ancak, sanirim arsiv arama olanagi cok eski olan mektuplari gostermiyor. (?)
Bir ay kadar sonra yeni Turkce C++ kitaplarina bakip yeni elestiriler yazacagim.
Managed C++ ogrenmekte bir sakinca olmayabilir. Ben onun ayrintilarini bilmiyorum ama hic olmazsa is bulma konusunda onemli olabilir.
C++'ta uzmanlasmak Ingilizce bilen benim icin 3-5 yil surdu (hala da ogreniyorum); onun icin kimsenin hevesi kirilmasin. :)
Guzel sozlerin icin de tesekkurler; Silikon Vadisi'ndeki bir suru Turk'ten birisiyim. Iyi oldugum konular da var kotu olduklarim da var; eksiklerimi tamamlamaya calisiyorum :)
Yabanci kitaplar konusunda accu.org'un 'Book Reviews'unu oneririm.
C ve C++ bolumlerinin ayrilmalari iyi bir fikir ama mektup sikligina bakarsak bunun o kadar da gerekli olmadigi dusunulebilir. (Bu karari ben vermiyorum.)
Ali
Arkantos
31/03/2004, 22:33
Ben de belki bir kaç saniye önce tam C dili sayfasındaki tüm kitap eleştirilerini okuduğumu ve sonuç olarak bu eleştirilere bakarak iyi hazırlanmış bir C++ kitabı yok kanaatine vardığımı (en azından Türkçe yazarlar tarafından) yazacaktım.
Sonuç olarak para falan önemli değil ama bir kitabı okumak benim için bir 6 ay demek. Bu yüzden dediğiniz gibi kitap eleştirileri önemli. Ve bu arada siz bu mesajı göndermeden önce Accu.Org'un "Highly Recommended" kısmını incelemiştim. Hatta bu mesajı yazıp sonradan göndermekten vazgeçtim.Gönderseymişim belki sizin mesajınızdan belki bir kaç saniye önce gidebilirmiş :)
İleride C++ ile ilgili bir kitap yazarsanız seviniriz. Bu arada en son konusuna geldiğim kitap C++ İle Nesneye Yönelik Programlama Dr.Yalçın Özkan Alfa Yayınları. Bu kitabı da tecrübeli birisi olarak kitap eleştirileri kısmında incelerseniz sevinirim. (Sanırım yoktu)
Forum Yazılımı : vBulletin v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.