Co do zasady, tak:
#include <iostream>
#include <cstddef>
class mat3 {
public:
mat3(); //Zadaniem konstruktora jest zerowanie tablicy za pomoca podwojnej petli
mat3(float v11, float v12, float v13,
float v21, float v22, float v23,
float v31, float v32, float v33); // Konstruktor z argumentami
void print() const; //Metoda wyswietlajaca macierz o rozmiarze 3x3
float * operator[](std::size_t rowIndex);
float get(std::size_t colIndex, std::size_t rowIndex) const;
void set(std::size_t colIndex, std::size_t rowIndex, float value);
private:
float data[3][3];
};
mat3::mat3() {
for(auto& row: data) {
for(auto& field: row) {
field = 0;
}
}
}
mat3::mat3(float v11, float v12, float v13,
float v21, float v22, float v23,
float v31, float v32, float v33)
: data{
{v11, v12, v13},
{v21, v22, v23},
{v31, v32, v33}
} {
}
void mat3::print() const {
for(auto& row: data) {
for(auto& field: row) {
std::cout << field << ' ';
}
std::cout << '\n';
}
}
float * mat3::operator[](std::size_t rowIndex) {
return data[rowIndex];
}
void mat3::set(std::size_t colIndex, std::size_t rowIndex, float value) {
data[rowIndex][colIndex] = value;
}
float mat3::get(std::size_t colIndex, std::size_t rowIndex) const {
return data[rowIndex][colIndex];
}
int main() {
mat3 m{1,2,3,4,5,6,7,8,9};
std::cout << "My matrix:\n";
m.print();
std::cout << "Access:\n";
std::cout << "[1][2] -> " << m[0][1] << '\n';
std::cout << "[3][3] -> " << m[2][2] << '\n';
std::cout << "Insert 100 in m[1][1]\n";
m[0][0] = 100;
std::cout << "Value [1][1] after insert:\n";
std::cout << "[1][1] -> " << m[0][0] << '\n';
std::cout << "My matrix:\n";
m.print();
std::cout << "Get & Set:\n";
m.set(2, 2, 42);
std::cout << "My matrix:\n";
m.print();
std::cout << "Get [3][3]:\n";
std::cout << m.get(2, 2) << '\n';
}
Co do logiki, wiele można tu poprawić i usprawnić.