Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Klasa imitująca klasę string (Szkoła programowania Praty r. 12)

Ostatnio zmodyfikowano 2016-08-09 12:49
Autor Wiadomość
Siedemdayz
Temat założony przez niniejszego użytkownika
Klasa imitująca klasę string (Szkoła programowania Praty r. 12)
» 2016-07-30 18:01:08
Zadanie 2 z rozdziału 12ego Szkoły programowania. W skrócie utwórz klasę imitującą klasę string.
Mamy gotowy listing funkcji głównej do którego należy dopisać deklarację klasy, wszystkie metody itd itd.
Problem występuje gdy chcę dodać const char * do obiektu nowej klasy ( const char * + obiekt ), a przeciążenie operatora działa tylko w odwrotnej kolejności tj ( obiekt + const char * ). Ktoś podpowie jak to trzeba zrobić?

Funkcja główna:
C/C++
#include <iostream>
#include <cctype>
#include "2.h"
using namespace std;

int main()
{
    Majtki s1( " i uczę się C++." );
    Majtki s2 = "Podaj swoję imię: ";
    Majtki s3;
    cout << s2; //Przeciążony operator <<
    cin >> s3; //Przeciążony operator >>
    s2 = "Mam na imię " + s3; //Przeciążone operatory = i +
    s2 = s2 + s1;
    s2.stringup(); //zamiana liter ciągu na wielkie
   
    cout << "Ciąg\n" << s2 << "\nzawiera " << s2.howmanychar( 'A' ) << " 'A'.\n";
   
    s1 = "czerwona"; //String(const char *)
    //a potem String & operator=(const String &)
    Majtki rgb[ 3 ] = { Majtki( s1 ), Majtki( "zielona" ), Majtki( "niebieska" ) };
    cout << "Podaj nazwę barwy podstawowej: ";
    Majtki ans;
    bool success = false;
   
    while( cin >> ans )
    {
        ans.stringlow(); //zamiana liter w ciągu na małe
        for( int i = 0; i < 3; ++i )
        {
            if( ans == rgb[ i ] ) //przeciążony operator ==
            {
                cout << "Prawidłowo!\n";
                success = true;
                break;
            }
        }
        if( success )
             break;
        else
             cout << "Spróbuj ponownie!\n";
       
    }
    cout << "Żegnam yo yo ! " << endl;
    return 0;
}

Deklaracja klasy:
C/C++
#ifndef NEWSTRING_H
#define NEWSTRING_H
#include <iostream>

using std::ostream;
using std::istream;

class Majtki
{
private:
    char * str; //wskaźnik ciągu
    int length; //długośc ciągu
    static int num_strings; //ile obiektów klasy
    static const int CINLIMIT = 80; //limicik na wejściu
public:
    Majtki( const char * s ); //konstruktor standardowy
    Majtki(); //konstruktor domyślny
    Majtki( const Majtki & ); //konstruktor kopiujący
    ~Majtki(); //destruktor
    int len() const { return length; }
    //przeciążanie operatorów
    Majtki operator +( const Majtki & );
    Majtki operator +( const char * );
    Majtki & operator =( const Majtki & ); //operator przypisania
    Majtki & operator =( const char * ); //przeciążony operator przypisania
    char & operator []( int i );
    const char & operator []( int i ) const; //niczym się nie różni poza const
    //funkcje zaprzyjaźnione:
    friend Majtki operator +( const char * s, const Majtki & st );
    friend bool operator <( const Majtki & st1, const Majtki & st2 );
    friend bool operator >( const Majtki & st1, const Majtki & st2 );
    friend bool operator ==( const Majtki & st1, const Majtki & st2 );
    friend ostream & operator <<( ostream & os, const Majtki & st );
    friend istream & operator >>( istream & is, Majtki & st );
    //metoda statyczna
    static int howmany();
    //metody dodatkowe cctype
    void stringlow();
    void stringup();
    int howmanychar( const char ch );
};

#endif

I te nieszczęsne rozwinięcia metod:
C/C++
#include <cstring>
#include <cctype>
#include "2.h"
using std::cin;
using std::cout;

int Majtki::num_strings = 0;

int Majtki::howmany()
{
    return num_strings;
}

Majtki::Majtki( const char * s )
{
    length = std::strlen( s );
    str = new char[ length + 1 ];
    std::strcpy( str, s );
    num_strings++;
}

Majtki::Majtki()
{
    length = 1;
    str = new char[ 1 ];
    str[ 0 ] = '\0';
    num_strings++;
}

Majtki::Majtki( const Majtki & st )
{
    length = st.length;
    str = new char[ length + 1 ];
    std::strcpy( str, st.str );
    num_strings++;
}

Majtki::~Majtki()
{
    --num_strings;
    cout << "Dokonano destrukcji!" << std::endl;
}

Majtki Majtki::operator +( const Majtki & st )
{
    char tmp[ CINLIMIT ];
    length = length + st.length;
    strcpy( tmp, str );
    delete[] str;
    str = new char[ length + 1 ];
    strcpy( str, tmp );
    strcat( str, st.str );
}

Majtki Majtki::operator +( const char * s )
{
    char tmp[ CINLIMIT ];
    length = length + std::strlen( s );
    strcpy( tmp, str );
    delete[] str;
    str = new char[ length + 1 ];
    strcpy( str, tmp );
    strcat( str, s );
}

Majtki & Majtki::operator =( const Majtki & st )
{
    if( this == & st )
         return * this;
   
    length = st.length;
    delete[] str;
    str = new char[ length + 1 ];
    std::strcpy( str, st.str );
    return * this;
}

Majtki & Majtki::operator =( const char * s )
{
    length = std::strlen( s );
    delete[] str;
    str = new char[ length + 1 ];
    std::strcpy( str, s );
    return * this;
}

char & Majtki::operator []( int i )
{
    return str[ i ];
}

const char & Majtki::operator []( int i ) const
{
    return str[ i ];
}

Majtki Majtki::operator +( const char * s, Majtki & st )
{
    return st + s;
}

bool operator <( const Majtki & st1, const Majtki & st2 )
{
    return( std::strcmp( st1.str, st2.str ) < 0 );
}

bool operator >( const Majtki & st1, const Majtki & st2 )
{
    return( std::strcmp( st1.str, st2.str ) > 0 );
}

bool operator ==( const Majtki & st1, const Majtki & st2 )
{
    return( std::strcmp( st1.str, st2.str ) == 0 );
}

ostream & operator <<( ostream & os, const Majtki & st )
{
    os << st.str;
    return os;
}

istream & operator >>( istream & is, Majtki & st )
{
    char tmp[ Majtki::CINLIMIT ];
    is.get( tmp, Majtki::CINLIMIT );
    if( is )
         st = tmp;
   
    while( is && is.get() != '\n' )
         continue;
   
    return is;
}

void Majtki::stringlow()
{
    for( int i = 0; i < length; i++ )
    {
        str[ i ] = tolower( str[ i ] );
    }
}

void Majtki::stringup()
{
    for( int i = 0; i < length; i++ )
    {
        str[ i ] = toupper( str[ i ] );
    }
}

int Majtki::howmanychar( const char ch )
{
    int counts;
    for( int i = 0; i < length; i++ )
    {
        if( str[ i ] == ch )
             counts++;
       
    }
    return counts;
}

Jeżeli post jest nieczytelny mogę też scalić 3 pliki w jeden. Problem występuje przy zaprzyjaźnionej funkcji przeciążającej operator +, mającej zwracać dodawanie czynników w odwrotnej kolejności. Błąd przy kompilacji: 2_2.cpp:96:53: error: ‘Majtki Majtki::operator+(const char*, Majtki&)’ must take either zero or one argument
P-150406
Gibas11
» 2016-07-30 19:10:25
Dwuargumentowy operator dodawania trzeba zdefiniować poza klasą.
//edit
Btw takie dodawanie stringów nie jest naprzemienne i Twoja implementacja operatora + da Ci złe wyniki.
P-150408
The_Wert
» 2016-08-09 12:49:32
Może spróbuj czegoś takiego: 

friend Majtki operator +( const char * s, const Majtki & st ) { return Majtki( s ) + st; }
P-150679
« 1 »
  Strona 1 z 1