Program na studia (przeciążenia, konstruktory...)

0

Mam na laboratoria do oddania program, a raczej dwa połączone. Napisane już troche mam natomiast po wywaleniu błędu stanęłam w martwym punkcie. Nie mam dodatkowych konsultacji z prowadzącym, musimy tylko oddawać gotowe projekty. Tutaj treści polecen:
screenshot-20210423183148.png
screenshot-20210423183224.png
A tutaj udostępniam mój program:
plik header.h

#ifndef HEADER_H
#define HEADER_H
#include <iostream>
#include <cstdio>

using namespace std;
class Macierz {
public:
    float** matrix; 						    	// tab dwuwymiarowa
    int m;
    int n;
    Macierz(); 									    // Konstr domyslny
    Macierz(const int m, const int n); 			    // Konstrukt tworzacy macierz o zadanych rozmiarach
    Macierz(double** matrix, int n, int m); 		// Konstr twarzacy macierz na podstawie tab przekazanej jako arg
    Macierz(const Macierz& obj); 		             // Konstr kopiujacy
    ~Macierz();      							    // Destruktor
    void changeDims(int m, int n); 				    // Funkcja mieniajaca rozmiar 
    int lcols(); 							        // Fun zwaracaca ilosc kolumn
    int lrows(); 							         // Fun zwracajaca ilosc wierszy
    void generateMacierz(); 						// fun generuja macierz z przecialu 0.0 do 1.0
    void printMacierz(); 							// fun wypisujaca macierz na ekranie


    Macierz& operator=(const Macierz& other);
    Macierz operator+(const Macierz& matrix);
    Macierz operator-(const Macierz& matrix);
    Macierz operator*(const float n);
    Macierz operator*(const Macierz& matrix);
    Macierz& operator*=(const float n);
    Macierz& operator*=(const Macierz& matrix);
    Macierz& operator+=(const Macierz& matrix);
    Macierz& operator-=(const Macierz& matrix);
    bool operator==(const Macierz& other);
    bool operator!=(const Macierz& other);
    float* operator[](int n);
    float operator()(int m, int n);
    friend std::ostream& operator<<(std::ostream& os, const Macierz& matrix);
    friend std::istream& operator>>(std::istream& is, const Macierz& matrix);
};

Macierz operator+(const Macierz& matrix1, const Macierz& matrix2) {
    Macierz outMacierz(matrix1.m, matrix1.n);
    for (int i = 0; i < matrix1.m; i++) {
        for (int j = 0; matrix1.n; j++) {
            outMacierz.matrix[i][j] = matrix1.matrix[i][j] + matrix1.matrix[i][j];
        }
    }
    return outMacierz;
}

Macierz operator-(const Macierz& matrix1, const Macierz& matrix2) {
    Macierz outMacierz(matrix1.m, matrix1.n);
    for (int i = 0; i < matrix1.m; i++) {
        for (int j = 0; matrix1.n; j++) {
            outMacierz.matrix[i][j] = matrix1.matrix[i][j] - matrix1.matrix[i][j];
        }
    }
    return outMacierz;
}

#endif

plik fun cpp

#include "header.h"

#include <cstdio>
using namespace std;


//Domyslny konstruktor 
Macierz::Macierz() { matrix = NULL; }//m,n 0

// Konstruktor tworzacy macierz o zadnych rozmiarach

Macierz::Macierz(const int m, const int n) {
    double** matrix = new double* [m];
    for (int i = 0; i < m; i++) matrix[i] = new double[n];

}

// Konstr twarzacy macierz na podstawie tab przekazanej jako arg

Macierz::Macierz(double** matrix, int m, int n) {
    /*double***/ matrix = new double* [m];
    for (int i = 0; i < m; i++) {
        matrix[i] = new double[n];
    }
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            matrix[i][j] = matrix[i][j];
        }
    }
}
// Konstr kopiujacy

Macierz::Macierz(const Macierz& obj) {
   this -> m = obj.m;
    this -> n = obj.n;//alokacja
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++)
        {
            matrix[i][j] = obj[i][j] ;//odwrotnie
        }
    }
    cout << "konstruktor kopiujacy działa" << endl;
}

// Destruktor


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


// Fun zwaracaca ilosc kolumn
int Macierz::lcols() {
    return this->m;
}
// Fun zwracajaca ilosc wierszy
int Macierz::lrows() {
    return this->n;
}

// Funkcja mieniajaca rozmiar pamieci
void Macierz::changeDims(int m, int n) {
    this->m = m;
    this->n = n;
    this->matrix = (float**)realloc(this->matrix, m * sizeof(float*));
    for (int i = 0; i < m; i++) {
        if (this->matrix[i] != nullptr) this->matrix[i] = (float*)realloc(this->matrix[i], n * sizeof(float));
        else this->matrix[i] = (float*)malloc(n * sizeof(float));
    }
}
// fun generuja macierz z przecialu 0.0 do 1.0
void Macierz::generateMacierz() {
    srand(time(NULL));
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            this->matrix[i][j] = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
        }
    }
}
// fun wypisujaca macierz na ekranie
void Macierz::printMacierz() {
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            cout << this->matrix[i][j] << " " << endl;
        }
        cout << endl;
    }
}

Macierz& Macierz::operator=(const Macierz& other) {
    if (this == &other) return *this;
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            this->matrix[i][j] = other.matrix[i][j];
        }
    }
    return *this;
}

Macierz Macierz::operator+(const Macierz& matrix) {
    Macierz outMacierz(this->m, this->n);
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            outMacierz.matrix[i][j] = this->matrix[i][j] + matrix.matrix[i][j];
        }
    }
    return outMacierz;
}

Macierz Macierz::operator-(const Macierz& matrix) {
    Macierz outMacierz(this->m, this->n);
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            outMacierz.matrix[i][j] = this->matrix[i][j] - matrix.matrix[i][j];
        }
    }
    return outMacierz;
}

Macierz Macierz::operator*(const float n) {
    Macierz outMacierz(this->m, this->n);
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            outMacierz.matrix[i][j] = this->matrix[i][j] * n;
        }
    }
    return outMacierz;
}

Macierz Macierz::operator*(const Macierz& other) {
    Macierz outMacierz(this->m, other.n);
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            outMacierz[i][j] = 0;
            for (int k = 0; k < other.m; k++) {
                outMacierz[i][j] += this->matrix[i][k] * other.matrix[k][j];
            }
        }
    }
    return outMacierz;
}

Macierz& Macierz::operator*=(const Macierz& other) {
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            this->matrix[i][j] *= other.matrix[i][j];
        }
    }
    return *this;
}

Macierz& Macierz::operator+=(const Macierz& matrix) {
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            this->matrix[i][j] += matrix.matrix[i][j];
        }
    }
    return *this;
}

Macierz& Macierz::operator-=(const Macierz& matrix) {
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            this->matrix[i][j] -= matrix.matrix[i][j];
        }
    }
    return *this;
}

Macierz& Macierz::operator*=(const float n) {
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            this->matrix[i][j] *= n;
        }
    }
    return *this;
}

bool Macierz::operator==(const Macierz& other) {
    if (this->m != other.m || this->n != other.n) return false;
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            if (this->matrix[i][j] != other.matrix[i][j]) return false;
        }
    }
    return true;
}

bool Macierz::operator!=(const Macierz& other) {
    if (this->m != other.m || this->n != other.n) return true;
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; this->n; j++) {
            if (this->matrix[i][j] != other.matrix[i][j]) return true;
        }
    }
    return false;
}

std::ostream& operator<<(std::ostream& os, const Macierz& matrix) {
    for (int i = 0; i < matrix.m; i++) {
        for (int j = 0; j < matrix.n; j++) {
            std::cout << matrix.matrix[i][j] << " ";
        }
        std::cout << endl;
    }
    return os;
}

std::istream& operator>>(std::istream& is, const Macierz& matrix) {
    for (int i = 0; i < matrix.m; i++) {
        for (int j = 0; j < matrix.n; j++) {
            is >> matrix.matrix[i][j];
        }
    }
    return is;
}

float* Macierz::operator[](int n) {
    if (n < 0 || n >= this->m) return nullptr;
    return this->matrix[n];
}

float Macierz::operator()(int m, int n) {
    if (m < 0 || m >= this->m || n < 0 || n >= this->n) return FLT_MAX;
    return this->matrix[m][n];
}

plik matrix.cpp

#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <float.h>
#include <string>
#include <cstdio>
#include "header.h"
using namespace std;



int main() {
    int m = 2;
    int n = 2;
    double** matrix = new double* [m];
    for (int i = 0; i < m; i++) {
        matrix[i] = new double[n];
    }
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            matrix[i][j] = 10;
        }
    }

    Macierz m1(m, n);
    m1.generateMacierz();
    Macierz m2(matrix, m, n);
    Macierz m3(m1);

    std::cout << " Macierz m1\n" << m1 << std::endl;
    std::cout << " Macierz m2\n" << m2 << std::endl;
    std::cout << " Macierz m3\n" << m3 << std::endl;


    std::cout << "Kolumny: " << m1.lcols() << std::endl;
    std::cout << "Wiersze: " << m1.lrows() << std::endl << std::endl;
    std::cout << " Macierz m1" << std::endl;
    m1.printMacierz();
    std::cout << std::endl;

    Macierz m5(2, 2);
    m5 = m1;
    std::cout << " m5\n" << m5 << std::endl;

    std::cout << " m2+m1\n" << m2 + m1 << std::endl;
    std::cout << " m2-m1\n" << m2 - m1 << std::endl;

    std::cout << " m1*5\n" << m1 * 5 << std::endl;
    std::cout << " m2*m2\n" << m2 * m2 << std::endl;

    m1 += m2;
    std::cout << " m1+=m2\n" << m1 << std::endl;
    m1 -= m2;
    std::cout << " m1-=m2\n" << m1 << std::endl;

    bool are_equal = (m1 == m2);
    std::cout << " m1 i m2 sa rowne:\n" << are_equal << std::endl;

    bool are_not_equal = (m1 != m2);
    std::cout << "\n m1 i m2 nie sa rowne: \n" << are_not_equal << std::endl;

    std::cout << "\n m2[1][1]\n" << m2[1][1] << std::endl;
    std::cout << "\n m2(1,1)\n" << m2(1, 1) << std::endl;

    Macierz m6(2, 2);
    std::cout << "\nWpisz macierz 6: ";
    std::cin >> m6;
    std::cout << m6;
}

Może będzie chciało sie komuś w rzucić to w kompilator dojść do tych błędów, a jeśli nie to dołączam

screenshot-20210423183551.png

Z góry dzięki za zainteresowanie!

3

Masz napisane - nie znaleziono operator[], który przyjmuje const Macierz. Czemu? Bo metoda nie jest oznaczona jako const:
https://docs.microsoft.com/en-us/cpp/cpp/const-cpp?view=msvc-160#const-member-functions

0

Potrzebujesz dwa operatory []

void checkbound(int n) { if((0 >n)||(n>=m)) throw exception("Index out of bound"); }
float &Macierz::operator[](int n) { checkbound(n); return matrix[n]; } // dla zapisu
const float &Macierz::operator[](int n)const { checkbound(n); return matrix[n]; } // dla odczytu
3

No dobra, kiepsko się robi review na forum, ale tutaj masz garść porad:

edy ta napisał(a):
class Macierz {
public:
    float** matrix; 						    	// tab dwuwymiarowa

Polecam zamienić float** matrix; na vector<vector<double>> matrix;
Polecam przenieść dane do private.

edy ta napisał(a):
    int m;
    int n;

Czy rozmiar macierzy może być ujemny? Jeżeli nie, to najlepiej poprawnie reprezentować typ, czyli size_t, ewentualnie jakiś uint32_t

edy ta napisał(a):
    Macierz(const int m, const int n); 			    // Konstrukt tworzacy macierz o zadanych rozmiarach

Ten const jest tutaj zbędny. Nie przekazujesz inta przez wkaźnik czy referencję by bronić się przed modyfikacją.

edy ta napisał(a):
    Macierz(double** matrix, int n, int m); 		// Konstr twarzacy macierz na podstawie tab przekazanej jako arg
    Macierz(const Macierz& obj); 		             // Konstr kopiujacy
    ~Macierz();      							    // Destruktor
    void changeDims(int m, int n); 				    // Funkcja mieniajaca rozmiar 

Część metod jest po polsku, część po angielsku, to jest niekonsekwentne. Sugeruję wybór jednego języka.

edy ta napisał(a):
    int lcols(); 							        // Fun zwaracaca ilosc kolumn
    int lrows(); 							         // Fun zwracajaca ilosc wierszy

A te metody są w obu językach - l od liczba; cols, rows wiadomo.
Dodatkowo funkcje powinny być oznaczone jako const.

edy ta napisał(a):
    void generateMacierz(); 						// fun generuja macierz z przecialu 0.0 do 1.0
    void printMacierz(); 							// fun wypisujaca macierz na ekranie

To samo.

edy ta napisał(a):
    bool operator==(const Macierz& other);
    bool operator!=(const Macierz& other);

Te metody nie powinny modyfikować zawartości macierzy. Zamień na:

bool operator==(const Macierz& other) const;
bool operator!=(const Macierz& other) const;
edy ta napisał(a):
    float* operator[](int n);

Brakuje operator[] z const jak zostało to już wspomniane.

edy ta napisał(a):
    friend std::ostream& operator<<(std::ostream& os, const Macierz& matrix);
    friend std::istream& operator>>(std::istream& is, const Macierz& matrix);

Jak masz implementację operatora <<, to po co printMacierz?

edy ta napisał(a):
Macierz::Macierz() { matrix = NULL; }//m,n 0

Ale m i n nie są nigdzie zainicjowane na 0.
Jakbyś użył std::vector to implementacja byłaby prostsza

Macierz::Macierz(const int m, const int n) :  matrix(m, vector<int>(n, 0)), m(m), n(n) { }
edy ta napisał(a):
Macierz::Macierz(const Macierz& obj) {
    this -> m = obj.m;
    this -> n = obj.n;//alokacja
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++)
        {
            matrix[i][j] = obj[i][j] ;//odwrotnie
        }
    }
    cout << "konstruktor kopiujacy działa" << endl;
}

Nie zapomniałeś o czymś? Przecież matrix jest niezaalokowane.

edy ta napisał(a):
void Macierz::changeDims(int m, int n) {
    this->m = m;
    this->n = n;
    this->matrix = (float**)realloc(this->matrix, m * sizeof(float*));
    for (int i = 0; i < m; i++) {
        if (this->matrix[i] != nullptr) this->matrix[i] = (float*)realloc(this->matrix[i], n * sizeof(float));
        else this->matrix[i] = (float*)malloc(n * sizeof(float));
    }
}

realloc dla pamięci z new? Bardzo zły nawyk.

edy ta napisał(a):
void Macierz::generateMacierz() {
    srand(time(NULL));
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            this->matrix[i][j] = static_cast <float> (rand()) / static_cast <float> (RAND_MAX);
        }
    }
}

https://en.cppreference.com/w/cpp/numeric/random

edy ta napisał(a):
Macierz& Macierz::operator=(const Macierz& other) {
    if (this == &other) return *this;
    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
            this->matrix[i][j] = other.matrix[i][j];
        }
    }
    return *this;
}

A jak rozmiary macierzy się nie zgadzają to co? Przecież program może się wywalić. To samo dla reszty funkcji.

edy ta napisał(a):
std::ostream& operator<<(std::ostream& os, const Macierz& matrix) {
    for (int i = 0; i < matrix.m; i++) {
        for (int j = 0; j < matrix.n; j++) {
            std::cout << matrix.matrix[i][j] << " ";
        }
        std::cout << endl;
    }
    return os;
}

Ta funkcja powinna wypisywać do os, a nie std::cout.

edy ta napisał(a):
float* Macierz::operator[](int n) {
    if (n < 0 || n >= this->m) return nullptr;
    return this->matrix[n];
}

Zwracanie nullptr to zły pomysł. Tutaj bym rzucił wyjątkiem.

edy ta napisał(a):
float Macierz::operator()(int m, int n) {
    if (m < 0 || m >= this->m || n < 0 || n >= this->n) return FLT_MAX;
    return this->matrix[m][n];
}

To samo, lepiej rzucić wyjątkiem.

2

Może jeszcze dodam:

    for (int i = 0; i < this->m; i++) {
        for (int j = 0; j < this->n; j++) {
  • http://forum.4programmers.net/1101404
  • użycie n,m,i,j dla tablic dwuwymiarowych jest błędogenna, użyj odpowiednio cols,rows,c,r ewentualnie width,height,w,h lub X,Y,x,y
  • używaj size_t do rozmiarów
  • łatwiej się czyta przy z listą inicjalizacyjną: np:
    -- Macierz::Macierz(const Macierz &m):rows(m.rows),cols(m.cols),data(bysize(rows,cols)) { copy(data,m.data); }
    -- Macierz::Macierz(size_t rows,size_t cols):rows(rows),cols(cols),data(bysize(rows,cols)) { zeros(data); }
  • mnożenie macierzy WTF? Tak się mnoży macierze?

1 użytkowników online, w tym zalogowanych: 0, gości: 1