acehreli
08/03/2007, 00:21
mesutbarlas adli uye artik devam etmeyecegini soyledigi bir tartismanin bir noktasinda kendi deyisiyle bir "C++ ornegi" verdi. Sanirim amaci bizlerin o kodu anlayip anlamayacagimizi gormekti. Ozellikle ~ isareti uzerinde durdugu icin, saniyorum bozucu islevi (destructor) anlayip anlamadigimizla ilgileniyordu.
C++ bilen herkes ~ ile baslayan islevin bozucu islev oldugunu bildigi icin, ben onu atlayacagim.
O kodun bir elestirisi:
/*
* Programla ilgisi olmayan bir baslik. Herhalde asagida gereksizce cagrilan getch()
* islevini derleyebilmek icin eklenmis olmali...
*/
#include <conio.h>
/*
* C++ dilinin standartlasmadigi donemden kalmis deneysel bir baslik. Artik bu basligin
* yerine <iostream> basligi var. Ustelik C++ standardinin 1998 yilinda kabul edildigini,
* <iostream.h>'nin ise ondan iki yil kadar once birakildigini hatirlarsak, bu programin
* cok eski bir C++ programcisi tarafindan yazildigini anlayabiliriz.
*/
/* #include <iostream.h> */
/*
* O yuzden ben dogru olan basligi, yani <iostream>'i ekliyorum
*/
#include <iostream>
#include <dos.h>
class hayat
{
private:
/*
* time'in ne oldugunu bilmedigim icin ben bu programi derleyemiyorum. :(
*
* Bu 't' nesnesinin hayat sinifi nesneleriyle hicbir ilgisi yok. Onun icin burada
* tanimlanmasi hata olmus. 't', hayat'in kurucu (constructor) ve bozucu (destructor)
* islevlerinde gecici olarak kullaniliyor. Her bir hayat nesnesinin buyuklugunu bu
* gereksiz nesne ile arttirmak yerine, 't' hayat'in kurucu ve bozucu islevlerinde
* yerel olarak tanimlanabilirmis.
*
* Hatta, bir asagida yapacagim oneri ile, 't'ye hic gerek bile yok...
*/
struct time t;
/*
* Son derece kotu tasarlanmis bir sinif. Programcinin bu kadar cok ve karmasik adin
* icinden cikmasi oldukca zor. Onun yerine, bu sinifin iki tane 'struct time' nesnesi
* icermesi cok yararli olurmus:
*
* struct time kurulma_zamani;
* struct time bozulma_zamani;
*
*/
int gec,gec2,saat1,dakika1,saniye1,salise1,saat2,dakik a2,saniye2,salise2,top,top2;
public:
hayat()
{
/*
* Burada zamani kurulma_zamani'nin icine alabilirdik.
*/
gettime(&t);
saat1=t.ti_hour;
dakika1=t.ti_min;
saniye1=t.ti_sec;
salise1=t.ti_hund;
}
~hayat()
{
/*
* Burada da zamani bozulma_zamani'nin icine alirdik. Boylece saat1, vs. gibi
* karmasik nesnelerle ugrasmak zorunda kalmazdik.
*/
gettime(&t);
saat2=t.ti_hour;
dakika2=t.ti_min;
saniye2=t.ti_sec;
salise2=t.ti_hund;
top=salise2-salise1;
gec2=salise2;
if (top<0)
{
gec2=100-saniye2;
//top=top*(-1);
gec=saniye2-1;
/*
* Bu iki satirdaki kod tekrarini goruyor musunuz? Iyi degil... :( Onun yerine,
* zamani ekrana yazdiran bir islev tanimlanmali ve o islev burada iki kere
* cagrilmalidir.
*/
cout<<saat1<<" "<<dakika1<<" "<<saniye1<<" "<<salise1<<" "<<endl;
cout<<saat2<<" "<<dakika2<<" "<<saniye2<<" "<<salise2<<" "<<endl;
/*
* Hmmm... Burada boyle hesaplarla vicik vicik ugrasmak yerine, iki tane 'struct
* time' nesnesinin farkini dOndUren bir islev yararli olmaz miydi. Bu hesaplara,
* ozellikle de gec ve gec2'nin anlasilmazliklarina hic bulasasim yok. Onun icin
* hesaplarin her durumda dogru olup olmadigindan da emin degilim.
*/
cout<<"OMUR="<<saat2-saat1<<" saat "<<dakika2-dakika1<<" dakika "<<gec-saniye1<<" saniye "<<100-((-1)*top)<<" salise";
}
else
{
gec=saniye2;
/*
* Ha ha! Bu asagidaki satirlar size de tanidik geliyor mu? :) Birisi "kod tekrari"
* mi dedi? Yanlis, yanlis... Bunlarin yerine yukarida adi gecen islevi cagiralim
* lutfen.
*/
cout<<saat1<<" "<<dakika1<<" "<<saniye1<<" "<<salise1<<" "<<endl;
cout<<saat2<<" "<<dakika2<<" "<<saniye2<<" "<<salise2<<" "<<endl;
cout<<"OMUR="<<saat2-saat1<<" saat "<<dakika2-dakika1<<" dakika "<<gec-saniye1<<" saniye "<<top<<" salise";
}
/*
* Ah! Ne buyuk bir hata... :( Her hayat nesnesi olusturuldugunda kullanicinin bir
* tusa basmasi gerekiyor. Super kullanissiz bir sinif... :(
*/
getch();
}
};
/*
* main'in dOnUs turu int'tir; degistiriyorum...
*/
/* void main() */
int main()
{
/*
* Ne? Ekranda bulunan bilgileri silmeye ne hakkimiz var! :) Neden kendi ciktimizla
* mutlu olmayi bilemiyoruz? Neden baskalarinin bilgilerini siliyoruz? :)
*/
clrscr();
/*
* n1 cok kotu bir nesne adi; ama olsun... :/
*/
hayat n1;
/*
* Bu ne ya?
*/
getch();
}
Dikkat ettiniz mi? hayat sinifinin kopyalayicisi yok. Eger main'in icine n1'in kopyasi olan baska bir nesne olustursak, o nesne de n1 ile ayni zamanda yasamina baslamis gibi gorulecektir. Sinifin tanimi bunu gerektiriyor olabilir ama ben bunu genelde yanlis buluyorum. Bence kopyalarin olustuklari ani da ozel olarak kaydetmek gerekirdi.
Ustelik, gorunuse gore amaci nesne yasam sureclerini belgelemek olan bir programin kopyalarin yasamlarini da dogru olarak vermesi cok yararli olurdu.
mesutbarlas, kodu verme amacinizi dogru olarak anlamis miyim? Bu kodla baska ne yapmamizi istiyordunuz acaba?
Ali
C++ bilen herkes ~ ile baslayan islevin bozucu islev oldugunu bildigi icin, ben onu atlayacagim.
O kodun bir elestirisi:
/*
* Programla ilgisi olmayan bir baslik. Herhalde asagida gereksizce cagrilan getch()
* islevini derleyebilmek icin eklenmis olmali...
*/
#include <conio.h>
/*
* C++ dilinin standartlasmadigi donemden kalmis deneysel bir baslik. Artik bu basligin
* yerine <iostream> basligi var. Ustelik C++ standardinin 1998 yilinda kabul edildigini,
* <iostream.h>'nin ise ondan iki yil kadar once birakildigini hatirlarsak, bu programin
* cok eski bir C++ programcisi tarafindan yazildigini anlayabiliriz.
*/
/* #include <iostream.h> */
/*
* O yuzden ben dogru olan basligi, yani <iostream>'i ekliyorum
*/
#include <iostream>
#include <dos.h>
class hayat
{
private:
/*
* time'in ne oldugunu bilmedigim icin ben bu programi derleyemiyorum. :(
*
* Bu 't' nesnesinin hayat sinifi nesneleriyle hicbir ilgisi yok. Onun icin burada
* tanimlanmasi hata olmus. 't', hayat'in kurucu (constructor) ve bozucu (destructor)
* islevlerinde gecici olarak kullaniliyor. Her bir hayat nesnesinin buyuklugunu bu
* gereksiz nesne ile arttirmak yerine, 't' hayat'in kurucu ve bozucu islevlerinde
* yerel olarak tanimlanabilirmis.
*
* Hatta, bir asagida yapacagim oneri ile, 't'ye hic gerek bile yok...
*/
struct time t;
/*
* Son derece kotu tasarlanmis bir sinif. Programcinin bu kadar cok ve karmasik adin
* icinden cikmasi oldukca zor. Onun yerine, bu sinifin iki tane 'struct time' nesnesi
* icermesi cok yararli olurmus:
*
* struct time kurulma_zamani;
* struct time bozulma_zamani;
*
*/
int gec,gec2,saat1,dakika1,saniye1,salise1,saat2,dakik a2,saniye2,salise2,top,top2;
public:
hayat()
{
/*
* Burada zamani kurulma_zamani'nin icine alabilirdik.
*/
gettime(&t);
saat1=t.ti_hour;
dakika1=t.ti_min;
saniye1=t.ti_sec;
salise1=t.ti_hund;
}
~hayat()
{
/*
* Burada da zamani bozulma_zamani'nin icine alirdik. Boylece saat1, vs. gibi
* karmasik nesnelerle ugrasmak zorunda kalmazdik.
*/
gettime(&t);
saat2=t.ti_hour;
dakika2=t.ti_min;
saniye2=t.ti_sec;
salise2=t.ti_hund;
top=salise2-salise1;
gec2=salise2;
if (top<0)
{
gec2=100-saniye2;
//top=top*(-1);
gec=saniye2-1;
/*
* Bu iki satirdaki kod tekrarini goruyor musunuz? Iyi degil... :( Onun yerine,
* zamani ekrana yazdiran bir islev tanimlanmali ve o islev burada iki kere
* cagrilmalidir.
*/
cout<<saat1<<" "<<dakika1<<" "<<saniye1<<" "<<salise1<<" "<<endl;
cout<<saat2<<" "<<dakika2<<" "<<saniye2<<" "<<salise2<<" "<<endl;
/*
* Hmmm... Burada boyle hesaplarla vicik vicik ugrasmak yerine, iki tane 'struct
* time' nesnesinin farkini dOndUren bir islev yararli olmaz miydi. Bu hesaplara,
* ozellikle de gec ve gec2'nin anlasilmazliklarina hic bulasasim yok. Onun icin
* hesaplarin her durumda dogru olup olmadigindan da emin degilim.
*/
cout<<"OMUR="<<saat2-saat1<<" saat "<<dakika2-dakika1<<" dakika "<<gec-saniye1<<" saniye "<<100-((-1)*top)<<" salise";
}
else
{
gec=saniye2;
/*
* Ha ha! Bu asagidaki satirlar size de tanidik geliyor mu? :) Birisi "kod tekrari"
* mi dedi? Yanlis, yanlis... Bunlarin yerine yukarida adi gecen islevi cagiralim
* lutfen.
*/
cout<<saat1<<" "<<dakika1<<" "<<saniye1<<" "<<salise1<<" "<<endl;
cout<<saat2<<" "<<dakika2<<" "<<saniye2<<" "<<salise2<<" "<<endl;
cout<<"OMUR="<<saat2-saat1<<" saat "<<dakika2-dakika1<<" dakika "<<gec-saniye1<<" saniye "<<top<<" salise";
}
/*
* Ah! Ne buyuk bir hata... :( Her hayat nesnesi olusturuldugunda kullanicinin bir
* tusa basmasi gerekiyor. Super kullanissiz bir sinif... :(
*/
getch();
}
};
/*
* main'in dOnUs turu int'tir; degistiriyorum...
*/
/* void main() */
int main()
{
/*
* Ne? Ekranda bulunan bilgileri silmeye ne hakkimiz var! :) Neden kendi ciktimizla
* mutlu olmayi bilemiyoruz? Neden baskalarinin bilgilerini siliyoruz? :)
*/
clrscr();
/*
* n1 cok kotu bir nesne adi; ama olsun... :/
*/
hayat n1;
/*
* Bu ne ya?
*/
getch();
}
Dikkat ettiniz mi? hayat sinifinin kopyalayicisi yok. Eger main'in icine n1'in kopyasi olan baska bir nesne olustursak, o nesne de n1 ile ayni zamanda yasamina baslamis gibi gorulecektir. Sinifin tanimi bunu gerektiriyor olabilir ama ben bunu genelde yanlis buluyorum. Bence kopyalarin olustuklari ani da ozel olarak kaydetmek gerekirdi.
Ustelik, gorunuse gore amaci nesne yasam sureclerini belgelemek olan bir programin kopyalarin yasamlarini da dogru olarak vermesi cok yararli olurdu.
mesutbarlas, kodu verme amacinizi dogru olarak anlamis miyim? Bu kodla baska ne yapmamizi istiyordunuz acaba?
Ali