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

metoda klasy string zwracajaca referencje do obiektu tej klasy.

Ostatnio zmodyfikowano 2016-11-16 23:37
Autor Wiadomość
mateczek
» 2016-11-16 01:17:01
basic_string & insert( size_type index, size_type count, CharT ch );
Działą tak jak klasa którą Ci przedstawiłem. coś robi na obiekcie i zwraca referencję do obiektu na rzecz którego pracuje.
C/C++
#include <iostream>
#include<string>
using namespace std;
int main()
{
    string s = { "Ala ma tygrysy" };
    cout << s.insert( 7, "2 " ) << endl; // ponieważ insert zwraca referencję do s mogę skorzystać i przesłać wynik metody do cout
}
P-153773
latajacaryba
Temat założony przez niniejszego użytkownika
» 2016-11-16 01:24:59
Ale czy ta metoda tworzy tą nową tablice? Bo w klasie przedstawionej przez Ciebie modyfikujemy składnik i zwracamy referencję do obiektu, a tu (z tego co zrozumiałem) tworzymy nową tablicę, przepisuje do niej tekst z naszym dodanym fragmentem innego cstringa i zwracamy referencję do obiektu. Tylko co teraz? Mamy dwie tablice? Czy tamta stara jest usuwana a ta zajmuje jej miejsce?
P-153774
mateczek
» 2016-11-16 01:32:36
jeśli chcesz zobaczyć jak zrobić poszerzającą się tablice. Czyli coś na wzór klasy Vector to był już taki wątek. I nie ma to nic wspólnego z zwrotem referencji do obiektu !!! http://cpp0x.pl/forum/temat/?id=23897&p=2
C/C++
#include <iostream>

class mTablica {
    int rozmiar; //rozmiar zaalokowanej pamięci(wielokrotność "base")
    int indexZapelneienia; //ile elementów jest w tablicy
    int * tab;
    int base = 10; //zaraz po utworzeniu tablica będzie miała base=10 elementów. Realokacja o kolejne 10 elementów nastąpi gdy będziemy chcieli zapisać 11 element
public:
    mTablica() {
        tab = new int[ base ];
        rozmiar = base;
        indexZapelneienia = 0;
    }
    ~mTablica() {
        delete[] tab;
    }
    //funkcje do komunikacji z klasą
    void pusback( int element ); //dodajemy element
    int & operator []( int index ); //zmieniamy lub odczytujemy element o znanym indexie - przeładowany operator
    int size() { return indexZapelneienia; } //funkcja zwraca rozmiar(zajętość, liczbę elementów) tablicy
   
};

//odkładanie elementu do tablicy
void mTablica::pusback( int element ) {
    if( indexZapelneienia >= rozmiar ) {
        //gdy rozmiar tablicy przekroczony zwiększam go o 10 elementów (realokacja)
        int * temp = new int[ rozmiar + base ];
        //kopiuje starą tablice do nowej
        for( int i = 0; i < rozmiar; i++ ) {
            temp[ i ] = tab[ i ];
        }
        //kasuje poprzednią
        delete[] tab;
        //aktualizuje wskaźnik
        tab = temp;
        //zwiększam rozmiar o base
        rozmiar = rozmiar + base;
    }
    //odkładam element
    tab[ indexZapelneienia++ ] = element;
}

int & mTablica::operator []( int index ) {
    return tab[ index ];
}


using namespace std;

int main()
{
    mTablica tab; // na początek tablica ma zaalokowaną pamięć na 10 elementów
    for( int i = 0; i < 35; i++ ) {
        tab.pusback( i ); //tablica się poszerzy 3 razy
    }
    tab[ 25 ] = 333; // mała wstawka
    //wyświetlam całą tablicę
    for( int i = 0; i < tab.size(); i++ ) {
        cout << tab[ i ] << " ";
    }
   
}

A każda metoda, która nie ma nic do zwracania może w ramach wykorzystania wolnego czasu zwrócić referencje do this.  W przedstawionym kodzie jedyna, która się do tego nadaje to metoda
"void pusback()" wystarczy dopisać return *this; i po sprawie :P
// tak by to wyglądało
C/C++
mTablica & mTablica::pusback( int element ) {
    if( indexZapelneienia >= rozmiar ) {
        //gdy rozmiar tablicy przekroczony zwiększam go o 10 elementów (realokacja)
        int * temp = new int[ rozmiar + base ];
        //kopiuje starą tablice do nowej
        for( int i = 0; i < rozmiar; i++ ) {
            temp[ i ] = tab[ i ];
        }
        //kasuje poprzednią
        delete[] tab;
        //aktualizuje wskaźnik
        tab = temp;
        //zwiększam rozmiar o base
        rozmiar = rozmiar + base;
    }
    //odkładam element
    tab[ indexZapelneienia++ ] = element;
    return * this;
}

na pytanie dlaczego zwracać referencję do "this" jest kilka odpowiedzi.
1 bo można
2 bo to prawie nic nie kosztuje "return *this;"
3 bo wywołania taśmowe są zajebiste. No chyba, że ktoś lubi taki kod jak niżej w 4 liniach klepać
cout << "ala ma" << lie << " koty" << endl;
P-153775
michal11
» 2016-11-16 08:31:30
insert w stringu nic nie tworzy tylko (tak jak nazwa wskazuje) wstawia do stringa znak/tekst na podanej pozycji, prototypowo wygląda to mniej więcej tak:
C/C++
string & insert( size_t pos, const string & str )
{
    char * newArr = new char[ size() + str.size() ];
   
    for( int i = 0; i < pos; ++i )
    {
        newArr[ i ] = _internalBuff[ i ];
    }
   
    for( int i = pos; i < pos + str.length(); ++i )
    {
        newArr[ i ] = str[ i ];
    }
   
    for( int i = pos + str.length(); i < length() + str.length(); ++i )
    {
        newArr[ i ] = _internalBuff[ i - str.length() ];
    }
   
    delete[] _interalBuff;
    _internalBuff = newArr;
   
    return * this;
}

Od razu uprzedzam bardziej zaawansowanych forumowiczów, że to jest tylko uproszczony schemat dla @latajacaryba i zdaję sobie sprawę, że faktycznie to wygląda zupełnie inaczej, ale koncepcja jest zapewne podobna.
P-153777
latajacaryba
Temat założony przez niniejszego użytkownika
» 2016-11-16 23:37:54
Dobra, przeanalizowałem. Z tego co zrozumiałem, to funkcja mogłaby być równie dobrze void, ale dzięki temu, że zwraca this możemy zrobić tak (przykład):
C/C++
string ala = "alama";
string kot = "kota";

cout << ala.insert( 5, kot );
//zamiast
ala.insert( 5, kot );
cout << ala;
Racja?
P-153813
1 2 « 3 »
Poprzednia strona Strona 3 z 3