[C++] Przeciążanie operatora '='

Witam, napisałem pewien program i podzieliłem go na 3 pliki:

main.cpp

#include 

#include "text.h" 

using namespace std; 


int main() 

{ 

    Text A("Ala"); 

    Text B("Ola"); 

    Text C; 

    C=A+B; 

    cout << C.pobierz() << endl; 

    return 0; 

}

text.cpp:

#include 

#include "text.h" 

#include 

Text::Text() 

{ 

    text = new char[1]; 

    text[0]='\0'; 

    dlugosc=0; 

} 

Text:: Text(const char * lancuch) 

{ 

    dlugosc = strlen(lancuch); 

    text = new char[dlugosc+1]; 

    strcpy(text,lancuch); 

    text[dlugosc] = '\0'; 

} 

Text::~Text() 

{ 

    delete [] text; 

} 

const Text & Text:: operator+ (const Text & obiekt) const 

{ 

    int c,i; 

    c = dlugosc +obiekt.dlugosc; 

    char *temp = new char[c+1]; 

    for(i=0;i
    { 

        temp[i] = text[i]; 

    } 

    for(int j=0;j
    { 

        temp[i] = obiekt.text[j]; 

    } 

    temp[c] = '\0'; 

    return temp; 

} 

Text & Text::operator=(const Text & obiekt) 

{ 

    delete [] text; 

    dlugosc = obiekt.dlugosc; 

    text = new char[dlugosc+1]; 

    cout << dlugosc << endl; 

    for(int i=0;i
    { 

        text[i] = obiekt.text[i]; 


    } 

    text[dlugosc] = '\0'; 


}

text.h:

#ifndef TEXT_H_INCLUDED 

#define TEXT_H_INCLUDED 

#include 

using namespace std; 

class Text 

{ 

    public: 

    Text(); 

    Text(const Text &); 

    Text(const char *); 

    Text & operator=(const Text &); 

    const Text & operator+(const Text &) const; 

    friend ostream& operator<<(ostream & , const Text &); 

    ~Text(); 

    const char* pobierz() const {return text;} 

    private: 

    char *text; 

    int dlugosc; 

}; 


#endif // TEXT_H_INCLUDED

Problem polega na tym, że program się kompiluje, ale się zawiesza, wiem, że problem leży w card.cpp w pętli Kod:

for(int i=0;i
    { 

        text[i] = obiekt.text[i]; 


    }

Jednak nie wiem, jak ją zmienić by działała poprawnie. Chcę by po napisaniu C=A+B wyświetliło “AlaOla”, po to przeciążałem operator ‘=’. Macie jakieś propozycje? Co ja źle napisałem w tej pętli?

Szybka poprawka:

const Text Text:: operator+ (const Text & obiekt) const

{

  int c,i;

  c = dlugosc + obiekt.dlugosc;


  // char *temp = new char[c+1];

  Text temp;

  temp.dlugosc = c;

  temp.text = new char[c + 1];


  for(i=0;i
    {

      temp.text[i] = text[i];

    }

  for(int j=0;j
    {

      temp.text[i] = obiekt.text[j];

    }


  return temp;

}

Rada na przyszłość: kompiluj z opcjami -Wall -pedantic. Po ostrzeżeniach od razu widać, że

Jednak zrzutowanie na char * wyjątkowo łatwo mu przyszło :expressionless: Dziwne…

Aha, i w operator= przydałoby się return *this;

Dzięki flash4gordon za poprawienie mojego kodu. Używam CodeBlocks, możesz mi powiedzieć, gdzie mogę ustawić opcje -Wall -pedantic?

Kolejne pytanie, dlaczego jeżeli napiszę const Text Text:: operator+ (const Text & obiekt) const to jest dobrze, a jak będzie const Text & Text:: operator+ (const Text & obiekt) const ( i oczywiście zmodyfikowaniu odpowiednio text.h) to program nie działa? I ostatnie, jaka będzie różnica, jak wpiszę return *this?

Program działałby nawet gdyby było tam const Text & Text:: operator+ (const Text & obiekt) const, ale jest to niepoprawne (w rozumieniu standardu) - jako, że zwracasz referencję, do obiektu który powinien już nie istnieć po wyjściu z funkcji. W przypadku zwracania przez wartość, zwracasz tak naprawdę ten sam obiekt, ale jako i r-wartość - nie ma swojego miejsca w pamięci (choć może istnieć na stosie), więc nie można przekazać go przez wskaźnik lub referencję, istnieje tylko przez wyrażenie i zostanie zaraz po tym zniszczony. Nie znam standardu C++ i pewnie trochę nazmyślałem, ale mniej więcej tak to wygląda.

Twój błąd polegał na tym, że zamiast obiektu Text zwrócony został char *.

return *this jest wymagane, gdyż zadeklarowane zostało takie coś:

Text & Text::operator=(const Text & obiekt)

co oznacza, że wartość zwrócona przez ten operator powinna być Text &, a jest void (czyli nic). this to specjalny wskaźnik, który wskazuje na obiekt, z którego została wywołana metoda. Przykład:

Text a, b, c;

a = b = c = Text("Ola");

W Code::Blocks będzie to settings->Compiler and Debugger zakładka Compiler flags szukaj Warnings

Kiedyś napisałem taki kod coby dało się prześledzić kiedy wołane odpowiednie są konstruktory i destruktory, może się przyda.

Używając kilku prostych zabiegów kod da się znacznie skrócić:

class Text{

Czyli w funkcji operator+ zwracam obiekt przez wartość, a po wyjściu z funkcji jest on niszczony.

W takim razie jest sens by w funkcji operator= była instrukcja “delete[]text”? Moim zamiarem było usunięcie obiektu wskazywanego przez temp.text w funkcji opeartor=, ale widzę, że źle to zrozumiałem. Co w takim razie usuwa to delete[]text w funkcji operator=?

delete[]text w funkcji operator=

usuwa starą zawartość obiektu aby za chwile przydzielić mu nową zawartość.

Jeżeli rozmiary przydzielonej pamięci nowej i starej są taki same to można pominąć zwolnienie starej i przydzielenie nowej.