c++实现简单矩阵类Mat

刚学习C++,之前把 Primer 看了一遍,现在也在刷 leetcode,感觉学习编程语言光看书页刷题也是不够的,最好是能做一些实际的项目,这样要用到哪些东西时不明白再看书,就会印象深刻些,否则光看书只是走马观花,看了也就忘了。
打算自己用C++实现一个简单的矩阵 Mat 类,包括一些简单的操作就可以了,但实现起来发现也并没有那么简单,还是遇到很多问题。这个过程也还是学到了不少东西。

固定数据类型的矩阵

先从一个固定数据类型的矩阵的开始吧,以 int 为例子,那么我们需要什么呢? 首先,我们需要记录矩阵的行和列,也需要一块内存存储矩阵的数据;然后需要一些简单的构造函数和其他的成员函数,实现一些基本的操作。
废话不多说,直接上程序:
头文件 Mat.h:

#ifndef _MAT_H_
#define _MAT_H_

#include <iostream>
#include <ostream>
#include <vector>
#include <cstring>
#include <cassert>

//implement Mat class in c++

class Mat{
    friend  std::ostream& operator<<(std::ostream &os, const Mat &m);
    friend  std::istream& operator>>(std::istream &is, Mat &m);

public:
    typedef int value_type;
    typedef std::vector<int>::size_type size_type;

    //construct
    Mat();
    Mat(size_t i, size_t j);

    //copy constructor
    Mat(const Mat& m);

    //copy assignment
    Mat& operator=(const Mat& m);

    // +=
    Mat& operator+=(const Mat& m);

    // -=
    Mat& operator-=(const Mat& m);

    //destructor
    ~Mat();

    //access element value
    int& operator()(size_t i, size_t j);
    const int& operator()(size_t i, size_t j) const;


    //get row and col number
    const size_t rows() const{ return row; }
    const size_t cols() const{ return col; }

    //resize
    void resize(size_t nr, size_t nc);

private:

    size_t row;
    size_t col;
    std::vector<std::vector<int>> data;
};

#endif

刚开始的时候,我是用 int* 来存储的数据,用int* 不方便的一个地方就是需要自己来管理内存,在实现一些 复制赋值和移动操作时都需要很小心处理,来管理内存,稍有不慎就会出问题。所以我后来改用C++标准容器 vector 了。这样就不用自己来管理内存了。

另外,像 + 、- 这样两边的数可以互换位置的操作符,重载时最好用非成员函数来重载,而且像 +=、 -= 这样的复合操作符,必须要用成员函数来重载。另外,可以用 +=、-= 来实现非成员函数的 + 、- 操作。最后要强调的是,非成员的运算符重载函数(+,-,,/)之类,返回类型应该是 const 类型,避免类似 a b = c 这样的语句通过编译。

像输出(<<)、输入(>>)运算符,需要用非成员函数来重载,一般还要声明为友元函数。不过可以通过成员函数完成输入输出操作,非成员函数来重载、调用成员函数输入输出来避免声明友元函数,后面一个例子就是这样实现的。

最后要强调的一点就是针对const对象,需要有对应的const版本的函数,具体说来,就是对一些不改变类类型的变量成员函数,尽量声明为const类型,这样const对象也能调用这些函数。在返回矩阵数据时,需要针对const 和 非const的对象,实现两个函数。

//access element value
int& operator()(size_t i, size_t j);
const int& operator()(size_t i, size_t j) const;

例如,重载 ( ) 运算符时,需要实现两个版本的函数,const 对象调用第二个版本函数,非 const 对象调用第一个版本的函数。

源文件Mat.cpp


#include <istream>
#include <sstream>
#include <algorithm>
#include "matint.h"


using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::stringstream;

ostream& operator<<(ostream &os, const Mat&m){
    for (size_t i = 0; i < m.row; i++){
        for (size_t j = 0; j < m.col; j++){
            os << m.data[i][j] << " ";
        }
        os << std::endl;
    }
    os << std::endl;
    return os;
}

istream& operator>>(istream &is, Mat&m){
    for (size_t i = 0; i < m.row; i++){
        for (size_t j = 0; j < m.col; j++){
            is >> m.data[i][j];
        }
    }
    return is;
}

// +
const Mat operator+(const Mat& m1, const Mat& m2){
    
  • 6
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值