Przeciążenie operatora +

Przeciążenie operatora +
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 5 lat
  • Postów:243
0

Witam. Bawię się właśnie przeciążeniem operatorów i chce przykładowo napisać program w którym gdy będę dodawał zmienne typu MojTyp to będą one w rzeczywistości mnożone. Mam tu jednak chyba jakieś problemy ze składnią.

Kopiuj
#include <iostream>

using namespace std;

class MojTyp
{
public:
    double zmienna;
    MojTyp(double z)
    {
        z=zmienna;
    }
};

MojTyp operator+(MojTyp a,MojTyp b)
{
    MojTyp suma;
    suma=a.zmienna*b.zmienna;
    return suma;
}

int main()
{
    return 0;
} 

Ktoś tu wie o co chodzi, bo jak na razie nie za bardzo ogarniam przeciążanie operatorów.

fasadin
  • Rejestracja:prawie 14 lat
  • Ostatnio:prawie 3 lata
  • Postów:4882
1

brakuje Ci konstruktora domyslnego

zawsze rob/napisz/zdefiniuj sobie tak zwana trojce na dzien dobry przy kazdej klasie
konstuktor domyslny
kostruktor kopiujacy
destruktor

edytowany 2x, ostatnio: fasadin
Zobacz pozostałe 2 komentarze
fasadin
tak masz racje ;) niedokladnie przeczytalem errora stad http://ideone.com/uoGZGc
MI
No więc dlaczego program się nie kompiluje, bo próbuje już od tygodnia rozgryźć przeciążanie operatorów.
fasadin
no przeciez napisalem Ci czego Ci brakuje, a Ty sie pytasz czemu sie nie kompiluje... wtf? Czytaj pierwsza linijke z postu az nie naprawisz swojego programu
Lucas Darkstorm
Lucas Darkstorm
@kq, dzięki za linka :). Ogarnę go sobie w wolnej chwili.
kq
Moderator C/C++
  • Rejestracja:prawie 12 lat
  • Ostatnio:około 6 godzin
  • Lokalizacja:Szczecin
1

Na przyszłość wklejaj błędy wypluwane przez kompilator, znacznie ułatwi to wszystkim życie.

Nie masz konstruktora domyślnego, a go używasz. Albo zaprzestań używania go, albo go zdefiniuj, trzeciej drogi nie ma. Przy okazji, powinieneś przyjmować argumenty przez const&, a nie przez kopię (chociaż akurat w tym przypadku ta regu​ła może nie mieć zastosowania - trzeba by było benchmarku).


edytowany 1x, ostatnio: kq
MarekR22
Moderator C/C++
  • Rejestracja:około 17 lat
  • Ostatnio:15 minut
3

Ja rozumiem, że przeciążanie operatorów to taka ładna błyskotka, na którą się rzuca każdy kto zaczyna.
Radzę jednak na razie skoncentrować swoje wysiłki na opanowaniu podstaw programowania obiektowego C++, wówczas bawienie się przeładowaniem operatorów przyjdzie samo.

Drugi problem to słuchaj kompilatora, on podpowiada w czym problem (clang jest w tym lepszy niż g++):

Kopiuj
x.cpp:17:12: error: no matching constructor for initialization of 'MojTyp'
    MojTyp suma;
           ^
x.cpp:9:5: note: candidate constructor not viable: requires single argument 'z', but no arguments were provided
    MojTyp(double z)
    ^
x.cpp:5:7: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 0 were provided
class MojTyp
      ^
1 error generated.

Jeden ze sposobów by to naprawić:

Kopiuj
MojTyp operator+(const MojTyp &a, const MojTyp &b)
{
    MojTyp suma(a.zmienna*b.zmienna);
    return suma;
}

Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
edytowany 2x, ostatnio: MarekR22
1
Kopiuj
#include <iostream>

struct A
{
	int a;

	A operator+(A const& o) {
		return A{ this->a + o.a };
	}
};

int main()
{
	A a1 { 2 };
	A a2 { 3 };
	A a3 = a1 + a2;

	std::cout << a3.a;

	return 0;
}
kq
brawo, właśnie zablokowałeś syntax 1+A{10} bo masz operator+ jako membera.
gośćabc
hmm a po co komu ten syntax? Masz wykonać A + A a nie num + A
kq
Napisz własne complex. Gratulacje, i + 1 działa, 1 + i już nie.
gośćabc
chodzi Ci o use case gdzie dodawanie/mnożenie jest nieprzemienne? bez takich pls, to nie o to w tym chodzi
kq
Dodawanie i mnożenie liczb zespolonych jest przemienne. Dlatego oba wypisane powyżej przeze mnie przykłady powinny działać.
vpiotr
  • Rejestracja:ponad 13 lat
  • Ostatnio:prawie 3 lata
1

Kod poprawiony przy minimalnej liczbie zmian:

Kopiuj
#include <iostream>
 
using namespace std;
 
class MojTyp
{
public:
    double zmienna;
    
    MojTyp(double z)
    {
        zmienna = z;
    }
    
	MojTyp operator+(const MojTyp &b)
	{
	    double z = this->zmienna * b.zmienna;
	    return MojTyp(z);
	}
};
 
 
int main()
{
	MojTyp a(0.1);
	MojTyp b(0.3);
	cout << "Wynik: " << (a+b).zmienna << endl;
    return 0;
} 
kq
Poprawny z operatorem+ jako funkcją klasy? Jeszcze bym zrozumiał gdyby OP tak miał, ale akurat to zrobił poprawnie...
vpiotr
Specjalnie napisałem o minimalnej liczbie zmian, bo ten kod nie jest idealny. 1) Jeśli wszystko publiczne to powinna być struktura (i operator nie membrowy). 2) Jeśli jednak klasa to pole prywatne, czyli trzeba użyć frienda do nie-membra, co dla mnie jest wytrychem - wole membra. Są jakieś przypadki kiedy muszę stosować nie-membra dla operator+ (poza enum) ?
kq
Zawsze, jeśli Twoja klasa ma niejawną konwersję z innych typów (ciężko mi wyobrazić sobie typ, w którym member operator+ ma sens). Tak jak wyżej napisałem, chociażby complex (inaczej nie dodasz 1+i) lub string (&quot;Hello, &quot; + world).
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 5 lat
  • Postów:243
0

Ogarnąłem liczbie zmian wystarzczy taki kod aby poprawnie działał.

Kopiuj
#include <iostream>

using namespace std;

class MojTyp
{
public:
    double zmienna;
    MojTyp(double z)
    {
        zmienna=z;
    }
};

MojTyp operator+(MojTyp a,MojTyp b)
{
    MojTyp suma=a.zmienna*b.zmienna;
    return suma;
}

int main()
{
    MojTyp x(3);
    MojTyp y(6);
    MojTyp z(0);
    z=x+y;
    cout << z.zmienna;
    return 0;
}
 
MI
  • Rejestracja:prawie 11 lat
  • Ostatnio:około 5 lat
  • Postów:243
0

Ogarnąłem! Przy minimalnej liczbie zmian wystarczy taki kod aby program poprawnie działał.

Kopiuj
#include <iostream>

using namespace std;

class MojTyp
{
public:
    double zmienna;
    MojTyp(double z)
    {
        zmienna=z;
    }
};

MojTyp operator+(MojTyp a,MojTyp b)
{
    MojTyp suma=a.zmienna*b.zmienna;
    return suma;
}

int main()
{
    MojTyp x(3);
    MojTyp y(6);
    MojTyp z(0);
    z=x+y;
    cout << z.zmienna;
    return 0;
}
 
edytowany 1x, ostatnio: Mikilll
Sarrus
Chyba chciałeś post edytować, ale coś nie wyszło ;)
twonek
Przecież od samego początku @fasadin i @kq Ci napisali co należy zrobić: wystarczy dodać MojTyp() {} do klasy.

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.