【c++实验一】CMatrix类设计与实现

这篇博客详细介绍了使用C++实现一个矩阵类(CMatrix)的过程,包括无参构造函数、带参数构造函数、拷贝构造函数和从文件构造函数。此外,还实现了析构函数、空间创建与释放、算术和关系运算符重载、下标操作、强制类型转换以及输入输出流操作。代码示例展示了如何定义矩阵、进行矩阵加法、设置元素值、比较矩阵以及从文件读写矩阵等操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验内容:

一、构造函数

CMatrix(): 不带参数的构造函数;
CMatrix(int nRow, int nCol, double *pData=NULL) : 带行、列及数据指针等参数的构造函数,并且参数带默认值;
CMatrix(const char * strPath): 带文件路径参数的构造函数;
CMatrix(const CMatrix& m): 拷贝构造函数
此外会用列表初始化成员变量:CMatrix(): m_nRow(0), m_nCol(0), m_pData(NULL);
bool Create(int nRow, int nCol, double *pData=NULL): 先删除原有空间,根据传入行列创建空间,如果pData不为空要将pData的内容拷贝到m_pData中。

二、析构函数

~CMatrix(): 调用Release();
Release(): 将内存释放,并将行列设置为0;

三、运算符重载

算术运算符重载:+, -, +=, -=
关系运算符重载:>, <, ==
下标操作符:[], ()
强制类型转换: double
赋值运算符:=,尤其注意当m1=m1特殊情况的处理

四、友元函数

输入和输出运输符:<<, >>

函数实现:

Cmatrix.cpp:

#include "CMatrix.h"
#include <fstream>
#include <assert.h>
CMatrix::CMatrix() : m_nRow(0), m_nCol(0), m_pData(0)
{

}
CMatrix::CMatrix(int nRow, int nCol, double* pData) : m_pData(0)
{
    Create(nRow, nCol, pData);
}
CMatrix::CMatrix(const CMatrix& m) : m_pData(0)
{
    *this = m;
}
CMatrix::CMatrix(const char* strPath)
{
    m_pData = 0;
    m_nRow = m_nCol = 0;
    ifstream cin(strPath);
    cin >> *this;
}
CMatrix::~CMatrix()
{
    Release();
}
bool CMatrix::Create(int nRow, int nCol, double* pData)
{
    Release();
    m_pData = new double[nRow * nCol];
    m_nRow = nRow;
    m_nCol = nCol;
    if (pData)
    {
        memcpy(m_pData, pData, nRow * nCol * sizeof(double));
    }
    return true;
}
void CMatrix::Release()
{
    if (m_pData)
    {
        delete[]m_pData;
        m_pData = NULL;
    }
    m_nRow = m_nCol = 0;
}
CMatrix& CMatrix::operator=(const CMatrix& m)
{
    if (this != &m) {
        Create(m.m_nRow, m.m_nCol, m.m_pData);
    }
    return *this;
}
CMatrix& CMatrix::operator+=(const CMatrix& m)
{
    assert(m_nRow == m.m_nRow && m_nCol == m.m_nCol);
    for (int i = 0; i < m_nRow * m_nCol; i++)
    {
        m_pData[i] += m.m_pData[i];
    }
    return *this;
}
CMatrix operator+(const CMatrix& m1, const CMatrix& m2)
{
    CMatrix m3(m1);
    m3 += m2;
    return m3;
}
double& CMatrix::operator[](int nIndex)
{
    assert(nIndex < m_nRow* m_nCol);
    return m_pData[nIndex];
}
double& CMatrix::operator()(int nRow, int nCol)
{
    assert(nRow * m_nCol + nCol < m_nRow* m_nCol);
    return m_pData[nRow * m_nCol + nCol];
}
bool CMatrix::operator == (const CMatrix& m)
{
    if (!(m_nRow == m.m_nRow && m_nCol == m.m_nCol))
    {
        return false;
    }
    for (int i = 0; i < m_nRow * m_nCol; i++)
    {
        if (m_pData[i] != m.m_pData[i])
        {
            return false;
        }
    }
    return true;
}
bool CMatrix::operator !=(const CMatrix& m)
{
    return !((*this) == m);
}
CMatrix::operator double()
{
    double dS = 0;
    for (int i = 0; i < m_nRow * m_nCol; i++)
    {
        dS += m_pData[i];
    }
    return dS;
}
istream& operator>>(istream& is, CMatrix& m)
{
    is >> m.m_nRow >> m.m_nCol;
    m.Create(m.m_nRow, m.m_nCol);
    for (int i = 0; i < m.m_nRow * m.m_nCol; i++)
    {
        is >> m.m_pData[i];
    }
    return is;
}
ostream& operator<<(ostream& os, const CMatrix& m)
{
    os << m.m_nRow << " " << m.m_nCol << endl;
    double* pData = m.m_pData;
    for (int i = 0; i < m.m_nRow; i++)
    {
        for (int j = 0; j < m.m_nCol; j++)
        {
            os << *pData++ << " ";
        }
        os << endl;
    }
    return os;
}

CMatrix.h:

#include <iostream>
using namespace std;
class CMatrix
{
public:
    CMatrix();
    CMatrix(int nRow, int nCol, double* pData = NULL);
    CMatrix(const CMatrix& m);
    CMatrix(const char* strPath);
    ~CMatrix();
    bool Create(int nRow, int nCol, double* pData = NULL);
    void Set(int nRow, int nCol, double dVale);
    void Release();
    friend istream& operator>>(istream& is, CMatrix& m);
    friend ostream& operator<<(ostream& os, const CMatrix& m);
    CMatrix& operator=(const CMatrix& m);
    CMatrix& operator+=(const CMatrix& m);
    double& operator[](int nIndex);
    double& operator()(int nRow, int nCol);
    bool operator==(const CMatrix& m);
    bool operator!=(const CMatrix& m);
    operator double();
private:
    int m_nRow;
    int m_nCol;
    double* m_pData;
};
CMatrix operator+(const CMatrix& m1, const CMatrix& m2);
inline void CMatrix::Set(int nRow, int nCol, double dVal)
{
    m_pData[nRow * m_nCol + nCol] = dVal;
}

Main.cpp:

#include <iostream>
#include <stdio.h>
#include "CMatrix.h"
using namespace std;
int main() {
    double pData[10] = { 2,3,4,5 };
    CMatrix m1, m2(2, 5, pData), m3("d:\\1.txt"), m4(m2);
    cin >> m1;
    m2.Set(1, 3, 10);
    cout << m1 << m2 << m3 << m4;
    m4 = m3;
    m4[2] = m4 + 1;
    cout << m4;
    if (m4 == m3)
    {
        cout << "Error !" << endl;
    }
    m4 += m3;
    cout << "sum of m4 = " << (double)m4 << endl;
    return 0;
}

构造函数:

CMatrix();
//不带参数的构造函数
CMatrix(int nRow, int nCol, double* pData = NULL);
//带行、列及数据指针等参数的构造函数,并且参数带默认值
CMatrix(const CMatrix& m);
//带文件路径参数的构造函数
CMatrix(const char* strPath);
//拷贝构造函数
bool Create(int nRow, int nCol, double* pData = NULL);
//先删除原有空间,根据传入行列创建空间,如果pData不为空要将pData的内容拷贝

析构函数:

~CMatrix();
//调用Release()
void Release();
//将内存释放,并将行列设置为0

运算符重载:

CMatrix & operator+=(const CMatrix & m);
double& operator[](int nIndex);
double& operator()(int nRow, int nCol);
bool operator ==(const CMatrix & m);
bool operator !=(const CMatrix & m);
operator double();

CMatrix & CMatrix:: operator += (const CMatrix &m)
//表示一个运算符重载函数
operator double()
//无需指明返回类型,double作为一个运算符,该函数用于double运算符重载

 友元函数:

    friend istream& operator>>(istream& is, CMatrix& m);
    friend ostream& operator<<(ostream& os, const CMatrix& m);

代码运行截图:

Introduction ============ This is a class for symmetric matrix related computations. It can be used for symmetric matrix diagonalization and inversion. If given the covariance matrix, users can utilize the class for principal component analysis(PCA) and fisher discriminant analysis(FDA). It can also be used for some elementary matrix and vector computations. Usage ===== It's a C++ program for symmetric matrix diagonalization, inversion and principal component anlaysis(PCA). To use it, you need to define an instance of CMatrix class, initialize matrix, call the public funtions, and finally, free the matrix. For example, for PCA, CMarix theMat; // define CMatrix instance float** C; // define n*n matrix C = theMat.allocMat( n ); Calculate the matrix (e.g., covariance matrix from data); float *phi, *lambda; // eigenvectors and eigenvalues int vecNum; // number of eigenvectors (<=n) phi = new float [n*vecNum]; lambda = new float [vecNum]; theMat.PCA( C, n, phi, lambda, vecNum ); delete phi; delete lambda; theMat.freeMat( C, n ); The matrix diagonalization function can also be applied to the computation of singular value decomposition (SVD), Fisher linear discriminant analysis (FLDA) and kernel PCA (KPCA) if forming the symmetric matrix appropriately. For data of very high dimensionality (n), the computation of nxn matrix is very expensive on personal computer. But if the number m of samples (vectors) is smaller than dimenionality, the problem can be converted to the computation of mxm matrix. The users are recommended to read the paper KPCA for how to form mxm matrix: B. Sch枚lkopf, A. Smola, K.-R. M眉ller. Nonlinear component analysis as a kernel eigenvalue problem, Neural Computation, 10(5): 1299-1319, 1998. Example ======= Refer to `example' directory for a simple demonstration.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值