• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Przeładowanie operatorów (dodawanie)

Object Storage Arubacloud
0 głosów
195 wizyt
pytanie zadane 13 kwietnia 2021 w C i C++ przez grzecho123 Początkujący (450 p.)
otagowane ponownie 13 kwietnia 2021 przez grzecho123

mam taki prosty programik tworzący macierz o zadanych rozmiarach. Użytkownik z klawiatury przesyła żądaną wielkość tej macierzy, a program wpisuje wartości do tych macierzy. Dodatkowo posiadam klasę, a macierz to po prostu obiekt. Prześlę na razie w fragmentach kod . oto mój plik:

#include <iostream>
#include <time.h>
#include "macierz.h"

using namespace std;

int main()
{
    srand(time(NULL));

    int M,N;
    cout<<"1.Utworzenie tablicy"<<endl;
    cout << "Podaj ilosc wierszy: " << endl;
    cin>>M;
    cout << "Podaj ilosc kolumn: " << endl;
    cin>>N;
    Macierz m1(M,N);
    m1.wypisz();


    float **tablica;
    tablica=new float*[M];
    for(int i=0; i<M; i++)
    {
        tablica[i]=new float[N];
    }

    for(int i=0; i<M; i++)
    {
        for (int j=0; j<N; j++)
        {
            tablica[i][j]=float(i+1)/float(j+1);
        }
    }

    Macierz m2(M,N),m3(M,N),m4(M,N),m5(M,N);
    cout<<"Jednoargumentowy +(1)"<<endl;
    m3+1;
    m3.wypisz();
    cout<<endl;

    cout<<"Jednoargumentowy -(1)"<<endl;
    m4-1;
    m4.wypisz();
    cout<<endl;

    cout<<"Przypisania ="<<endl;
    m5=1;
    m5.wypisz();
    cout<<endl;

    cout<<"+"<<endl;
    m5=m2+m3;
    m5.wypisz();
    cout<<endl;

    return 0;
}

To mój plik macierz.h

#include <iostream>

using namespace std;

class Macierz
{
        public:
    int m, n, x, y;
    float **macierz;

    Macierz(int=0,int=0);
    Macierz(float**,int,int);
    Macierz(Macierz &);
    ~Macierz();

    Macierz& operator+(int);
    Macierz& operator-(int);
    Macierz& operator=(int);

    Macierz operator+(Macierz);


    int wiersze();
    int kolumny();
    void wypisz();
    void generujlosowe();
    void zmienrozmiar(int=0, int=0);
};

a to macierz.cpp

#include <iostream>
#include "macierz.h"

using namespace std;

Macierz::Macierz(int w, int k)
{
    m=w;
    n=k;
    macierz=new float*[m];

    for(int i=0; i<m; i++)
    {
        macierz[i]=new float[n];
    }

    for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
        {
            macierz[i][j]=i+j;
        }
    }
    x=m;
    y=n;
}

Macierz::Macierz(float** tabl, int s, int k)
{
    m=s;
    n=k;
    macierz=new float*[m];

    for(int i=0; i<m; i++)
    {
        macierz[i]=new float[n];
    }
    for(int i=0; i<s; i++)
    {
        for(int j=0; j<k; j++)
        {
            macierz[i][j]=tabl[i][j];
        }
        cout<<endl;
    }
}

Macierz::~Macierz()
{
    for(int i = 0; i <m; ++i) {
        delete[] macierz[n];
    }
    delete[] macierz;
    macierz = NULL ;
}

void Macierz::wypisz()
{
    for(int i=0; i<m; i++)
    {
    for(int j=0; j<n; j++)
        {
            cout<<macierz[i][j]<<"   ";
        }
        cout<<endl;
    }
}
void Macierz::generujlosowe()
{
    float a = 0.0;
    float b = 1.0;
    for ( int i = 0 ; i < m ; i++) {
        for ( int k = 0 ; k < n ; k ++) {
            macierz[i][k] = ((float)rand() / RAND_MAX) * (b - a) + a;
        }
    }
}

void Macierz::zmienrozmiar(int d, int j)
{
    m=d;
    n=j;
    float **tablica;
    tablica=new float*[m];

    for(int i=0; i<m; i++)
    {
        tablica[i]=new float[n];
    }

    for(int i = 0; i <x; ++i) {
        delete[] macierz[y];
    }
    delete [] macierz;

    macierz=new float*[m];

    for(int i=0; i<m; i++)
    {
        macierz[i]=new float[n];
    }


}

Macierz::Macierz(Macierz &obiekt) {
    m = obiekt.m;
    n = obiekt.n;
    macierz = new float*[m];
    for ( int i = 0 ; i < m; i++) {
        macierz[i] = new float[n];
    }

    for ( int j = 0 ;j < m ; j++) {
        for ( int k = 0 ; k < n ; k++) {
            macierz[j][k] = obiekt.macierz[j][k];
        }
    }
}

int Macierz::wiersze()
{
    return m;
}

int Macierz::kolumny()
{
    return n;
}

Macierz& Macierz::operator+(int a1)
{
    for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
        {
            macierz[i][j]+=a1;
        }
    }
}
Macierz& Macierz::operator-(int a2)
{
     for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
        {
            macierz[i][j]-=a2;
        }
    }
}

Macierz& Macierz::operator=(int a3)
{
    for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
        {
            macierz[i][j]=a3;
        }
    }
}

Macierz Macierz::operator+(Macierz c1)
{
    Macierz d(*this);
    for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
        {
            d.macierz[i][j]+=c1.macierz[i][j];

        }
    }

    return d;
}

Noi m i n to są poprostu wartości pobrane z klawiatury czyli rozmiar tej macierzy. Przechowywane są one w klasie. Robiłem testy czy mi gdzieś nie zmienia tych wartości program i wszystko jest okej wartości sprawdzałem przed samym wywołaniem m5.wypisz(). Bo jeśli wpiszę wartości, ktore mają taki sam rozmiar na przykład 4 i 4 to wszystko ładnie dodaje natomiast jeśli zmienię wartości np 4 i 5 to juz sie sypie i wychodzą jakieś wartości "2.56507e-038" i nic nie działa albo jak wpiszę 4 i 9 to mi 2 pierwsze wiersze psuje a 2 kolejne są ok. 

2 odpowiedzi

+2 głosów
odpowiedź 13 kwietnia 2021 przez tangarr Mędrzec (154,860 p.)
wybrane 14 kwietnia 2021 przez grzecho123
 
Najlepsza

1. Funkcje operator+(int) i operator-(int) nie powinny modyfikować obiektu. Zmień je na += i -=
2. Operatory powinny zwracać wartość (return *this)
3. Nieprawidłowo zwalniasz pamięć
4. Brakuje ci operatora Macierz& operator=(Macierz&). Operator automatycznie tworzony przez kompilator działa nieprawidłowo.
Jeżeli chcesz zobaczyć jak powinien wyglądać ten program zajrzyj tutaj ale najpierw postaraj się sam naprawić te problemy.

komentarz 13 kwietnia 2021 przez grzecho123 Początkujący (450 p.)

okej narazie spróbuję sam

1. Okej rozumiem natomiast w zadaniu mam napisane aby stworzyć przeładowanie operatorów:

  • jednoargumentowy +
  • jednoargumentowy -

Właśnie zastanawiam się jak to zrobić. Czy w pętli dać return macierz[i][j]+a1 ? Nie wiem też czy można tyle razy używać return.

2. Wszystkie operatory powinny zwracać return *this?

3. Szczerze nie wiem jaki mam błąd.

4. Co ten operator ma za zadanie zrobić? Jest mi on potrzebny do tego aby dodać 2 obiekty?

 

komentarz 13 kwietnia 2021 przez tangarr Mędrzec (154,860 p.)

Operatory + i - nie powinny zwracać nową macierz a nie modyfikować istniejącą.
Wszystkie funkcje zwracające wartość muszą zwracać wartość! Jeżeli typem zwracanym przez funkcję jest referencja na typ to powinieneś zwracać *this lub refencję do jakiegoś obiektu nie tymczasowego.
Operator

Macierz operator=(Macierz& macierz)

ma za zadanie przeprowadzić poprawną operację przypisania jednej macierzy do drugiej.

Operator domyślny kopiuje wszystkie pola z przypisywanej macierzy wraz ze wskaźnikiem na tablicę.
W linii

m5=m2+m3;

najpierw jest wykonywany operator Macierz::operator+(Macierz&),
tworzony jest obiekt tymczasowy,
następnie wszystkie pola tego obiektu (m,n,x,y,macierz) są kopiowane do obiektu m5,
potem obiekt tymczasowy jest niszczony (zwalniana jest również pamięć zajmowana przez pole macierz).
W efekcie czego zmienna m5.macierz wskazuje na zwolnioną pamięć.
Operator Macierz::operator=(Macierz&) działa podobnie do konstruktora kopiującego Macierz::Macierz(Macierz&). Musi się tylko upewnić, że rozmiar macierzy jest zgodny (czyli usunąć ją i utworzyć na nowo jeżeli macierz, którą chcemy skopiować ma inny rozmiar) i na koniec zwraca referencję na obiekt.

komentarz 14 kwietnia 2021 przez grzecho123 Początkujący (450 p.)
Dzięki za wyjaśnienie i przesłanie kodu. Postaram się to wszystko zrozumieć. :D
komentarz 15 kwietnia 2021 przez grzecho123 Początkujący (450 p.)

Operatory + i - nie powinny zwracać nową macierz a nie modyfikować istniejącą.

A mógłbyś mi napisać jak to zrobić żeby operator był jednoargumentowy ale bez modyfikacji istniejącej macierzy?

1
komentarz 15 kwietnia 2021 przez tangarr Mędrzec (154,860 p.)
class Class {
private:
    int mValue;
public:
    Class(int value) : mValue(value) {}
    Class operator+(const Class &other) const {
        return Class(mValue+other.mValue);
    }
};

 

+1 głos
odpowiedź 14 kwietnia 2021 przez TOM_CPP Pasjonat (22,640 p.)
edycja 14 kwietnia 2021 przez TOM_CPP

Jeżeli nie musisz w zadaniu używać operatora new, to pomyśl o zastosowania kontenera std::vector. Zamiast surowego wskaźnika ( float** macierz; ) będziesz miał:

vector<vector<float>> macierz;

i dalej w konstruktorze

 macierz.resize(w);
 for( auto& row : macierz ) row.resize(k,0.0f);

Zaletą tego rozwiązani jest, że kontener std::vector ma już napisane konstruktory/operatory kopiujące,przenoszące. Nie musisz także implementować własnego destruktora, gdyż w momencie usunięcia obiektu wywołany będzie automatycznie destruktor kontenera.

komentarz 14 kwietnia 2021 przez grzecho123 Początkujący (450 p.)
Dziękuję :) Na pewno przyda się informacja.

Podobne pytania

0 głosów
2 odpowiedzi 493 wizyt
pytanie zadane 9 czerwca 2017 w C i C++ przez niezalogowany
0 głosów
1 odpowiedź 917 wizyt
pytanie zadane 21 czerwca 2015 w C i C++ przez Bartaz Początkujący (440 p.)
0 głosów
4 odpowiedzi 603 wizyt
pytanie zadane 25 września 2017 w JavaScript przez adrian588 Początkujący (470 p.)

92,632 zapytań

141,500 odpowiedzi

319,879 komentarzy

62,013 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...