Заранее извеняюсь, если вопрос вам заставит долго читать, но так как вопросов не очень много, решил позволить себя...
Реализован класс:
class Matrix {
using Rep = std::valarray<double>;
using S = std::slice;
public:
Matrix(const size_t, const size_t);
Matrix subMatrix(const size_t, const size_t,
const size_t);
template < class Cont >
Matrix& assign(const Cont&, size_t, size_t);
Rep& get_rep() { return *pv; }
const size_t size() const { return pv->size(); }
Rep row(size_t index) const;
Rep column(size_t index) const;
//...
private:
size_t x, y;
std::shared_ptr<Rep> pv;
friend std::ostream& operator <<(std::ostream& os, const Matrix& m)
{
for (double d : *m.pv) {
static size_t k = 0;
if(k && !(k % m.y)) os << std::endl;
++k;
os << std::fixed << std::setprecision(2)
<< std::setw(8) << std::left << d;
}
return os;
}
};
Matrix::Matrix(const size_t row, const size_t column)
: x(row), y(column), pv(new Rep(x * y)) {}
Matrix
Matrix::subMatrix(const size_t row, const size_t column, const
size_t start)
{
if ((start + row * column) > size())
throw " out of range ";
Matrix m(row, column);
Rep& v = *pv;
*m.pv = v[std::gslice(start, {row, column}, {y, 1})];
return m;
}
Matrix&
Matrix::assign(const Cont &list, size_t w, size_t h)
{
if (w && h) {
const size_t sz = std::distance(std::begin(list), std::end(list));
size_t n = w * h;
while (n > sz && w > 1) n = (--w) * h;
if (n > sz) n = sz;
*this = Matrix(w, h);
std::copy_n(std::begin(list), n, std::begin(*pv));
}
return *this;
}
Matrix::Rep
Matrix::row(size_t row) const
{ row %= x; return Rep((*pv)[S(row * y, y, 1)]); }
Matrix::Rep
tvm::Matrix::column(size_t column) const
{ column %= y; return Rep((*pv)[S(column, x, y)]); }
Обеспечены некоторые необходимые функциональности. Теперь я могу написать программу:
Matrix m(5, 6);
// матрица как std::valarray
std::valarray<double>& v = m.get_rep();
// инициализируем значениями [1, 30]
std::iota(begin(v), end(v), 1);
// вычитаем 0.05 со всех элементов
v -= 0.05;
//min и max значения
std::cout << "min_element: " << v.min() << std::endl
<< "max_element: " << v.max() << std::endl;
//составляем новую матрицу из первых двух строк
//по 3 элемнета каждой строки, следующие 3 для второй матрицы
Matrix m1 = m.subMatrix(2, 3, 0),
m2 = m.subMatrix(2, 3, 3); //вторая половина
std::cout << m << std::endl << std::endl << m1 << std::endl << m2;
// ну и т.д. и т.п.
Вывод:
min_element: 0.95
max_element: 29.95
0.95 1.95 2.95 3.95 4.95 5.95
6.95 7.95 8.95 9.95 10.95 11.95
12.95 13.95 14.95 15.95 16.95 17.95
18.95 19.95 20.95 21.95 22.95 23.95
24.95 25.95 26.95 27.95 28.95 29.95
0.95 1.95 2.95
6.95 7.95 8.95
3.95 4.95 5.95
9.95 10.95 11.95
В последних операциях, матрицы копируются. Первый вопрос по этому поводу.Насколько я понимаю умные указатели std::shared_ptr
при копировании оба указателья будут ссылаться на обьект копируемого, ресурс под другой обьект освободится. Учитывая этот факт я выбрал именно этот указатель, чтобы все копировалось по умолчанию и корректно. Так вот:
Как видно из программы, я получаю ссыльку на преставление матрицы и пользуясь эффективными и удобными методами std::valarray
, могу выполнить различные действия над матрицей, легко и эффективно. По этому поводу второй вопрос:
Старался быть немногословным(наверное не очень получилось)
Например у меня есть функция int foo() {return 0;};И где нибудь в main я буду вызывать foo() , а как оператор () работает в данном случае ?
Какая библиотека на C++ существует для рисования SVG? Использовать буду в Qt, а встроенный отрисовщик в Qt не очень шустрый
Тут я как всегда не вовремя задумался вот над каким вопросомПри выделении памяти из кучи очевидно, что в куче должна сохраняться информация...