Przeciążanie operatorów. Kilka pytań.

Przeciążanie operatorów. Kilka pytań.
bajos
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:UwUdź
  • Postów:267
0

Witajcie,

Trzeba się w końcu nauczyć przeciążanie operatorów. Czytałem jakieś tam kursy (w tym ten na 4p). Nie mam pojęcia czym się różni w przeciążaniu operatorów, że typ zwracany/argumenty jest referencją lub nie i czym się różni const& od zwykłego &. Co to zmienia?


128 postów [25.06.2015r. 21:03]
twonek
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:2500
1

czym się różni const& od zwykłego &

Kopiuj
void f(int& a)
{
    a = -11;	
}

void g(const int& a)
{
    a = -33;
}

void h(int a)
{
    a = 5;
}

g się nie skompiluje, bo a jest referencją na stałą, więc nie możesz jej modyfikować. h praktycznie nic nie robi, bo a jest kopią tego argumentu, który podałeś do funkcji.

Nie mam pojęcia czym się różni w przeciążaniu operatorów, że typ zwracany jest referencją

Jeśli typ zwracany nie jest referencją, to znaczy że jest nowym obiektem. A co najważniejsze obiektem tymczasowym, przez co np. taki kod nie przejdzie:

Kopiuj
x = y = z = w;

W tym przypadku potrzebujesz, żeby wynik x = y był referencją, dzięki czemu możesz przypisać do niego z. A potem do wyniku tego przypisać w.

bajos
@twonek, a mogę zawsze zwracać referencję czy są przypadki, że nie można bo coś będzie źle działać? Bo jak jest referencja to oszczędność pamięci (może niewielka ale zawsze). A jeśli jako prawy operand (?) operatora podam zmienną, która nie będzie const to nie ruszy?
twonek
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:2500
0

a mogę zawsze zwracać referencję czy są przypadki, że nie można bo coś będzie źle działać?

Jak masz

Kopiuj
c = a + b

to raczej powinieneś tworzyć nowy obiekt. No bo jeśli zwracasz referencję powiedzmy do a (żeby nie było wątpliwości, nie możesz zwracać referencji do tymczasowego obiektu, jak referencja to tylko do czegoś istniejącego - w przypadku x = y modyfikujesz x i zwracasz referencję do niego), wyobraź sobie takie coś:

Kopiuj
c = a + b;         // dodaje b do a, a potem zwraca referencję do a
c = nowa_wartosc;         // ups, a teraz też ma nowa_wartosc

A jeśli jako prawy operand (?) operatora podam zmienną, która nie będzie const to nie ruszy?
No taka jest idea const, do tego służy.

MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:2 minuty
0
bajos napisał(a):

Witajcie,

Trzeba się w końcu nauczyć przeciążanie operatorów. Czytałem jakieś tam kursy (w tym ten na 4p). Nie mam pojęcia czym się różni w przeciążaniu operatorów, że typ zwracany/argumenty jest referencją lub nie i czym się różni const& od zwykłego &. Co to zmienia?

A po co? to jest taki błyszczący feature jeżyka, na który rzucają się wszyscy początkujący.
Moja rada opanuj dobrze język, napisz kilka programów z kodem powyżej 200 linii i dopiero wtedy wróc do tematu przeciążania operatorów. Wtedy okaże się, że temat jest prosty.

To samo dotyczy wielowątkowości (jednak tu próg wymaganych minimalnych umiejętności jest znacznie wyższy).


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
bajos
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:UwUdź
  • Postów:267
0

@twonek,

g się nie skompiluje, bo a jest referencją na stałą, więc nie możesz jej modyfikować.
a tutaj http://cpp0x.pl/dokumentacja/standard-C++/Przeciazanie-operatorow/operator/1045 jest dobrze, a przecież

Kopiuj
 TypDanychT wartosc; 

nie jest stałą?


128 postów [25.06.2015r. 21:03]
twonek
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:2500
0

Nie widzę żadnego powiązania między moim zdaniem a tym co napisałeś.

Nie widzę żadnej stałej w tym kodzie, który pokazałeś. Dlaczego w ogóle myślisz, że zwykła zmienna jest stałą?

Beznadziejny przykład w tym kursie, bo żadnego przypisania tam nie ma.

bajos
  • Rejestracja:prawie 12 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:UwUdź
  • Postów:267
0

Napisaem sobie:

Kopiuj
 
/* .hpp */
#ifndef LINEPROCESSOR
#define LINEPROCESSOR

#include <string>

class LineProcessor {
protected:
    std::string source;
    unsigned int pointer;
public:
    explicit LineProcessor();
    explicit LineProcessor(std::string &str);
    std::string readTo(char chars[]);
    std::string readToBetween(char pairs[]);

    LineProcessor& operator=(const std::string &str);
};

#endif // LINEPROCESSOR

/* KONIEC .hpp*/
/* .cpp */

LineProcessor& LineProcessor::operator=(const std::string &str)
{
    source = str;
    pointer = 0;
    return *this;
}
/* KONIEC .cpp*/

/* Tak wyglada uzycie*/
LineProcessor lineProc();
lineProc = "linia1234xyz";                 // linia 11

qDebug() << lineProc.readTo("24y");  // linia 13

QtCreator pokazuje takie bledy:

Kopiuj
/home/patryk/projekty/BennuModelEditor/LoadingThread.cpp:11: błąd: assignment of function 'LineProcessor lineProc()'
     lineProc = "linia1234xyz";
              ^
/home/patryk/projekty/BennuModelEditor/LoadingThread.cpp:11: błąd: cannot convert 'const char [13]' to 'LineProcessor()' in assignment

/home/patryk/projekty/BennuModelEditor/LoadingThread.cpp:13: błąd: request for member 'readTo' in 'lineProc', which is of non-class type 'LineProcessor()'
     qDebug() << lineProc.readTo("24y");
                          ^

Wyglada na to ze chce wywolac konstruktor zamiast przeciazyc operator;

// PS. Jak wylaczyc alt jako klawisz skrotu do menu bar w Unity? Nie moge uzyc polskich znakow.


128 postów [25.06.2015r. 21:03]
edytowany 3x, ostatnio: bajos
twonek
  • Rejestracja:prawie 11 lat
  • Ostatnio:prawie 2 lata
  • Postów:2500
1
Kopiuj
LineProcessor lineProc();

Tutaj deklarujesz funkcję o nazwie lineProc, która przyjmuje 0 parametrów i zwraca obiekt typu LineProcessor.
To co chciałeś osiągnąć to:

Kopiuj
LineProcessor lineProc;

Ogólnie reguły parsowania w C++ mówią, że jeśli można coś traktować jako deklarację funkcji, to właśnie tak zostanie traktowane. To jest jeszcze bardziej porypane jeśli bierze się pod uwagę, że nazwa funkcji w pewnych sytuacjach jest opcjonalna, więc

Kopiuj
SomeClass x(LineProcessor())

może być traktowane jako funkcja o nazwie x, która zwraca obiekt SomeClass, a przyjmuje jako parametr funkcję (bez nazwy) która zwraca LineProcessor i przyjmuje 0 parametrów.

Po więcej szczegółów możesz googlować "the most vexing parse c++".

kaczus
  • Rejestracja:około 10 lat
  • Ostatnio:8 dni
  • Lokalizacja:Łódź
  • Postów:1402
0

jak chcesz wywołać:

Kopiuj
lineProc.readTo("24y");

to deklaracja winna wyglądać:

Kopiuj
std::string readTo(const char *chars);

natomiast linia 11 wymaga rzutowania.


Ogólnie na prace domowe mam stawki zaporowe. Czasem coś o programowaniu znajdzie się na mojej stronie

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.