HATA NEREDE?

Başlatan mr.engineer, 23 Ağustos 2020, 20:08:30

mr.engineer

Aşağıdaki kodda uzun bir string girildiği zaman (SIZE>10) sadece SIZE adet eleman "String" class tanımlı bir object'e kaydedilecek. Eğer SIZE<10 şeklinde bir string girilirse, girilen string olduğu şekilde kaydedilecek.

#include <iostream>
#include <cstring>
#include <string.h>
using namespace std;

class String
{
protected:
    enum { SIZE = 10 };
    char str[SIZE];
public:
    String()
    {
        str[0] = 0;
    }
    String(char a[])
    {
        cout << "burası calismiyor" << endl;
        strcpy(str, a);
    }
    void display()
    {
        cout << str << endl;
    }
    operator char* ()
    {
        return str;
    }
};

class Pstring: public String   //Derived class
{
public:
    
    Pstring(char s[])
    {
        if (strlen(s) < SIZE)
        {
            String(s);
        }
        else
        {
            strncpy(str, s, SIZE - 1);
            str[SIZE - 1] = 0;
        }
    }
};
int main()
{
    Pstring s1=(char*)("short");
    Pstring s2 = (char*)("tooooo long string");
    s1.display();
    s2.display();
}



Mainde verilen s2 objecti'ni ekrana yazdırabiliyorum ama kısa olan s1 çalışmıyor. Gördüğüm kadarıyla "String" class'ındaki "one-argument constructor" çalışmıyor.

Neresi hatalı anlayamadım. C++'da yeniyim o yüzden bilmediğim veya gözden kaçan bir şey olabilir.

zfr35

Merhaba,
String(s); çağrımı ile bir obje yaratılmamaktadır. Ayrıca bu çağrım ile Pstring objesinin str dizisini doldurmayı düşündüysen eğer bu düşüncen de yanlış olur. En azından aşağıdaki gibi bir kopyalama işlemi yapılabilir ki bu işlemde yine bir kötü kodlama örneğididir. C++ deneme yanılma ile öğrenilecek bir dil olarak görmüyorum. Bir kitap eşliğinde öğrenilmeli.

        if (strlen(s) < SIZE)
        {
            ::memcpy(this->operator char *(), String(s).operator char *(), strlen(s)+1);
        }

mr.engineer

Alıntı yapılan: zfr35 - 23 Ağustos 2020, 23:38:25Merhaba,
String(s); çağrımı ile bir obje yaratılmamaktadır. Ayrıca bu çağrım ile Pstring objesinin str dizisini doldurmayı düşündüysen eğer bu düşüncen de yanlış olur. En azından aşağıdaki gibi bir kopyalama işlemi yapılabilir ki bu işlemde yine bir kötü kodlama örneğididir. C++ deneme yanılma ile öğrenilecek bir dil olarak görmüyorum. Bir kitap eşliğinde öğrenilmeli.

        if (strlen(s) < SIZE)
        {
            ::memcpy(this->operator char *(), String(s).operator char *(), strlen(s)+1);
        }

Hocam bu kod kitapta olan kod. Aynen bu şekilde verilmiş. Bu kullanımı ben de görmedim daha önce. Bir constructor'da başka bir constructor çağırıken genelde şu şekilde yapılıyor:

class Pstring: public String
{
public:
   
    Pstring(char s[]): String(s)
    {;}
.
.
.
.
}

Bu şekilde çağırılınca doğru çalışıyor ama "String(s)" ifadesini bir alt satıra parantez içine yazdığımızda çalışmıyor. Bu yöntem yanlışsa kitapta neden böyle bir kod verilmiş anlamadım.

this->operator şeklinde bir şey şimdilik bilmediğimden yazdığınız kodu anlayamadım ama bakacağım tekrar.

Başka yorum yapabilecek varsa öğrenmek isterim.

brandice5

#3
Cunku if blogu icerisinde "String(s);" ile yeni bir String objesi yaratip, bu objenin str dizisine yaziyorsun ama bu object local oldugu icin if blogunun disina cikinca bellekten siliniyor. Ayrica bu sekilde hicbir degiskene atanmamis oluyor.
Aslinda calistigini gormek icin if icini sununla dene;

if (strlen(s) < SIZE)
{
    String tmp = String(s);
    cout << (char*)tmp << "\n";
}

Derleyici optimizasyon yaptigi icin senin kodunda "burası calismiyor" yazisini goremezsin.

mr.engineer

O halde bu ifade bir constructor vazifesi görmüyor.
Ben derived class'a ait bir obje tanımlıyorum mainde. Bu şekilde olmuyorsa nasıl bu objeye, bir string kaydedebilirim?
Her türlü bir condition kullanmam gerekiyor. 

brandice5

@zfr35 in verdigi ornek gibi yapabilirsin, ya da else incinde yaptigin ayni sekilde strcpy ile yapilabilir.

Tabi bu islem icin neden iki class kullaniliyor anlamak guc, gercek dunyada mantiksiz bir tasarim.

mr.engineer

Alıntı yapılan: brandice5 - 24 Ağustos 2020, 17:27:36@zfr35 in verdigi ornek gibi yapabilirsin, ya da else incinde yaptigin ayni sekilde strcpy ile yapilabilir.

Tabi bu islem icin neden iki class kullaniliyor anlamak guc, gercek dunyada mantiksiz bir tasarim.


Hocam sadece alıştırma sorusu. C++ da yeniyim. Kitaptaki çözüm bu şekildeydi. Dediğiniz şekilde strcpy ile yapmıştım da bir de kitaptaki gibi yapmayı denedim.
Teşekkürler.

brandice5

Hangi kitap bu? Cunku kitapdaki kod ilk mesajindaki kod ile birebir ayni ise kitapda bir yanlislik var demektir.

mr.engineer

Alıntı yapılan: brandice5 - 24 Ağustos 2020, 18:21:23Hangi kitap bu? Cunku kitapdaki kod ilk mesajindaki kod ile birebir ayni ise kitapda bir yanlislik var demektir.


Object-Oriented Programming in C++ (4th Edition) by Robert Lafore

Chapter 9/ Exercise soru 2
Cevap da appendix kısmında

brandice5

Kitapdaki cevabi inceledim. Kitapdaki kodda baska bir hatada var, for icinde tanimladigi degiskeni for disinda kullanmaya calismis. Kod orjinal haliyle derlenmiyor bile. Yazar sanirim kitapdaki cevaplari ögrencilere filan hazirlatmis.

Yerinde olsam bu antik kitabi birakip (basim yili 2002 görünüyor) en azindan C++11 i anlatan daha guncel bir kitaba gercerdim.

mr.engineer

Alıntı yapılan: brandice5 - 25 Ağustos 2020, 17:01:06Kitapdaki cevabi inceledim. Kitapdaki kodda baska bir hatada var, for icinde tanimladigi degiskeni for disinda kullanmaya calismis. Kod orjinal haliyle derlenmiyor bile. Yazar sanirim kitapdaki cevaplari ögrencilere filan hazirlatmis.

Yerinde olsam bu antik kitabi birakip (basim yili 2002 görünüyor) en azindan C++11 i anlatan daha guncel bir kitaba gercerdim.


Şimdiye kadar ilk defa yanlış bir koda denk geldim. İnternette araştırdığımda bu kitap çok öneriliyordu ondan bu kitapla başladım.
Güncelden kastınız nedir tam bilmiyorum (yeni kitaplarda ciddi bir farklılık var mı?) ama önereceğiniz bir kitap varsa paylaşırsanız sevinirim.
Teşekkürler

brandice5

Guncelden kastim modern C++ (smart pointers, lambda expressions vs.) anlatan bir kitap.

Surada detayli bir liste var, bunlari inceleyebilirsin.

https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list

Surpriz bir sekilde senin kullandigin kitap bu listede yok.

mr.engineer