Experimental environment
Operating system: win10
gcc: 8.1.0
Development software vscode dev
Experimental content
1, Constructor
CMatrix(): constructor without parameters;
CMatrix(int nRow, int nCol, double *pData=NULL): constructor with parameters such as row, column and data pointer, and parameters with default values;
CMatrix(const char * strPath): constructor with file path parameter;
CMatrix (const CMatrix & M): copy constructor
in addition, the member variable will be initialized with the list: CMatrix(): m_nRow(0), m_nCol(0), m_pData(NULL);
bool Create(int nRow, int nCol, double *pData=NULL): first delete the original space and create a space according to the incoming row and column. If pData is not empty, copy the content of pData to m_pData.
2, Destructor
~ CMatrix(): call Release();
Release(): release the memory and set the row and column to 0;
3, Operator overloading
arithmetic operator overload: +, -, + =-=
overloading of relational operators: >, <==
subscript operators: [], ()
forced type conversion: double
assignment operator: =, pay special attention to the handling of special cases when m1=m1
4, Friend function
Input and output transportation symbols: <, > >
Experimental description
The CMatrix class in this experiment is essentially a three-dimensional array, which actually refers to a matrix, in which the first and second dimensions are the length and width of the matrix in turn, and the value of the third dimension is an array, that is, it refers to the sequentially ordered values in the matrix; The main purpose of this experiment is to test the implementation of different constructors and overloaded methods with CMatrix class as an example.
CMatrix.h
#ifndef CMATRIX_H #define CMATRIX_H #include <iostream> using namespace std; class CMatrix { public: // constructor CMatrix(); CMatrix(int nRow, int nCol, double *pData=NULL); CMatrix(const CMatrix &m); CMatrix(const char *strPath); ~CMatrix(); // Initialize object method bool Create(int nRow, int nCol, double *pData=NULL); // Free memory method void Release(); // Sets the method of the specified object void Set(int nRow, int nCol, double dVale); // Overloading Operator friend istream & operator>>(istream& is, CMatrix & m); friend ostream & operator<<(ostream& os, const CMatrix &m); // overload operators CMatrix& operator=(const CMatrix &m); CMatrix& operator+=(const CMatrix &m); CMatrix& operator-=(const CMatrix& m); bool operator ==(const CMatrix& m); bool operator !=(const CMatrix& m); double & operator[](int nIndex); double & operator()(int nRow, int nCol); // Overload type conversion operator double(); private: int m_nRow; int m_nCol; double *m_pData = NULL; }; // overload operators CMatrix operator+(const CMatrix& m1, const CMatrix& m2); CMatrix operator-(const CMatrix& m1, const CMatrix& m2); // Sets the method of the specified object inline void CMatrix::Set(int nRow, int nCol, double dVal) { m_pData[nRow*m_nCol+nCol]=dVal; } #endif
There is not much to say about the header file; It should be noted that
#ifndef CMATRIX_H #define CMATRIX_H ....... //Medium strategy #endif
Used to prevent heavy references
using namespace std;
It is used to declare the namespace. When calling a C + + library such as this, you need to declare the namespace; std is a namespace in which all identifiers in the C + + standard library are stored.
CMatrix.cpp
CMatrix::CMatrix():m_nRow(0),m_nCol(0),m_pData(0) //Use a parameterless constructor of an initialization expression to pass parameters in the order in which the class is defined { } CMatrix::CMatrix(int nRow,int nCol,double*pData):m_pData(0) //Parametric constructor { Create(nRow, nCol, pData); } CMatrix::CMatrix(const CMatrix& m) : m_pData(0) //copy constructor { *this = m; } CMatrix::CMatrix(const char* strPath) //External data constructor { m_pData = 0; m_nRow = m_nCol = 0; ifstream cin(strPath); cin >> *this; }
The above functions are four kinds of object constructors, and their respective categories are described in the above comments. The create function called by the constructor with parameters is given below. At the same time, in c + +, the * this in the above code actually refers to the newly constructed object.
CMatrix::~CMatrix() //Destructor, which is automatically executed after the object is called { Release(); } bool CMatrix::Create(int nRow, int nCol, double* pData) //New object method { 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() //Release object method { if (m_pData) { delete[]m_pData; m_pData = NULL; } m_nRow = m_nCol = 0; }
The create function is used to create a new object, which is mentioned in the parameter constructor; The remaining two functions are used as destructors. Destructors refer to that once the life cycle of an object class is completed after it is established, the destructor will be called automatically, and release will automatically empty the memory used by it, so as to release the object
istream& operator>>(istream& is, CMatrix& m) //operators overloading { 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) //operators overloading { 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& CMatrix::operator=(const CMatrix& m) //Assignment overload { if(this!=&m){ Create(m.m_nRow, m.m_nCol,m.m_pData); } return*this; } CMatrix& CMatrix::operator+=(const CMatrix& m) //Relational operation overload { 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& CMatrix::operator-=(const CMatrix& m) //Relational operation overload { 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) //Operator overloading { CMatrix m3(m1); m3 += m2; return m3; } double& CMatrix::operator[](int nIndex) //operators overloading { assert(nIndex < m_nRow* m_nCol); return m_pData[nIndex]; } double&CMatrix::operator()(int nRow,int nCol) //operators overloading { assert(nRow* m_nCol* nCol+nCol<m_nRow*m_nCol); return m_pData[nRow * m_nCol + nCol]; } bool CMatrix::operator ==(const CMatrix& m) //Relational operator overloading { 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) //Relational operator overloading { return!((*this) == m); } CMatrix::operator double() //Type conversion overload { double ds = 0; for (int i = 0;i < m_nRow * m_nCol;i++) { ds += m_pData[i]; } return ds; }
The above shows the overloading of various operators and operators required by the title; The concept of overloading is a derivative concept of class, which also exists in java programming languages. In short, overloading means that more than one method with the same name is allowed in the same class, as long as their parameter number or parameter type are different. In c + +, as shown above, it is composed of operator keyword + refactored object; It should be noted that not all methods can be refactored, such as destructors.
Main.cpp
Not much to say, let's stick the code below first
#include <iostream> #include <stdio.h> #include "CMatrix.h" using namespace std; int main(int argc, char** argv) { double pData[9]={7,7,7,3,3,3}; CMatrix CMatrix1, CMatrix2(3,3,pData), CMatrix3("C:\\Users\\28968\\Desktop\\C++\\test.txt"), CMatrix4; cout<<"please input the value of CMatrix1\n"; cin >> CMatrix1; CMatrix2.Set(3,3,3737); CMatrix4=CMatrix3; CMatrix4[0] = 9999; cout<<"CMatrix1:\n"<<CMatrix1<<"CMatrix2:\n"<<CMatrix2<<"CMatrix3:\n"<<CMatrix3<<"CMatrix4:\n"<<CMatrix4; CMatrix4 += CMatrix3; cout<<"CMatrix4 += CMatrix3:\n"<<CMatrix4; return 0; }
First of all, 4 new CMatrix classes are called in main, and no parametric constructors are used respectively. Parametric constructor; External data constructor and copy constructor. In addition, we first assign a value to CMatrix1 to test whether the overloading of the operator is successful, modify the value of CMatrix4 and output it in turn to check whether each overload and constructor are effective. Finally, sample whether the overloading of the + = operator is successful.
The above figure shows the content of test.txt.
It can be observed that the experimental results are as expected.
Summary
This experiment is expected to use vscode to complete the experiment, but there are some problems in the software configuration, which makes the software unable to read the engineering c + + software and can only run a separate c + + code; When running engineering code, you will always be prompted when applying the header file that the definition of the method of the class cannot be found.