繪本館網(wǎng)站建設(shè)百度服務(wù)
作者:非妃是公主
專欄:《C++》
博客地址:https://blog.csdn.net/myf_666
個(gè)性簽:順境不惰,逆境不餒,以心制境,萬事可成?!鴩?guó)藩
文章目錄
- 專欄推薦
- 一、類的聲明及函數(shù)定義
- 二、錯(cuò)誤信息
- 三、問題解決
- 1. 解決過程
- 2. 全部代碼
- 四、總結(jié)
- the end……
專欄推薦
專欄名稱 | 專欄地址 |
---|---|
軟件工程 | 專欄——軟件工程 |
計(jì)算機(jī)圖形學(xué) | 專欄——計(jì)算機(jī)圖形學(xué) |
操作系統(tǒng) | 專欄——操作系統(tǒng) |
軟件測(cè)試 | 專欄——軟件測(cè)試 |
機(jī)器學(xué)習(xí) | 專欄——機(jī)器學(xué)習(xí) |
數(shù)據(jù)庫 | 專欄——數(shù)據(jù)庫 |
算法 | 專欄——算法 |
一、類的聲明及函數(shù)定義
類的聲明及 *運(yùn)算符重載
函數(shù)聲明如下:
定義如下:
值得注意的是,上面的 +
和 -
兩個(gè)運(yùn)算符的重載并沒有問題。存在問題的是 *
運(yùn)算符的重載,看似和上面一樣,但是卻報(bào)出了如下錯(cuò)誤。
二、錯(cuò)誤信息
已啟動(dòng)生成...
1>------ 已啟動(dòng)生成: 項(xiàng)目: P2022_10, 配置: Debug x64 ------
1>22_矩陣.cpp
1>D:\C++Code\leCoPractice\P2022_10\22_矩陣.cpp(35,28): error C2143: 語法錯(cuò)誤: 缺少“;”(在“<”的前面)
1>D:\C++Code\leCoPractice\P2022_10\22_矩陣.cpp(36): message : 查看對(duì)正在編譯的 類 模板 實(shí)例化“Matrix<T>”的引用
1>D:\C++Code\leCoPractice\P2022_10\22_矩陣.cpp(35,19): error C2460: “*”: 使用正在定義的“Matrix<T>”
1>D:\C++Code\leCoPractice\P2022_10\22_矩陣.cpp(35,1): error C2433: “*”: 不允許在數(shù)據(jù)聲明中使用“friend”
1>D:\C++Code\leCoPractice\P2022_10\22_矩陣.cpp(35,1): error C2473: “operator *”: 看起來像函數(shù)定義,但卻沒有參數(shù)列表。
1>D:\C++Code\leCoPractice\P2022_10\22_矩陣.cpp(35,1): error C2238: 意外的標(biāo)記位于“;”之前
1>D:\C++Code\leCoPractice\P2022_10\22_矩陣.cpp(124,11): error C2365: “*”: 重定義;以前的定義是“數(shù)據(jù)變量”
1>D:\C++Code\leCoPractice\P2022_10\22_矩陣.cpp(35): message : 參見“*”的聲明
1>D:\C++Code\leCoPractice\P2022_10\22_矩陣.cpp(35,19): error C2460: “*”: 使用正在定義的“Matrix<int>”
1>D:\C++Code\leCoPractice\P2022_10\22_矩陣.cpp(150): message : 參見“Matrix<int>”的聲明
1>D:\C++Code\leCoPractice\P2022_10\22_矩陣.cpp(193,19): error C3861: “multi”: 找不到標(biāo)識(shí)符
1>已完成生成項(xiàng)目“P2022_10.vcxproj”的操作 - 失敗。
========== “生成”: 0 成功,1 失敗,0 更新,0 已跳過 ==========
如果你也報(bào)出了相同的錯(cuò)誤,那么可以繼續(xù)往后看下去。
三、問題解決
1. 解決過程
因?yàn)檫@個(gè)問題涉及到了模板,而自己平時(shí)對(duì)于模板的編寫并不熟練。
首先,需要說明一點(diǎn)的是,C++
的運(yùn)算符重載一般有兩種方式,
- 采用友元的方式,比如重載輸入輸出運(yùn)算符。
- 另一種方式是采用成員函數(shù)的形式。
具體的定義方式,可以去網(wǎng)上查看一些實(shí)例代碼,在此不再贅述。
在檢索了網(wǎng)絡(luò)上的一些矩陣模板類,我最終的解決方法是:把友元函數(shù)的重載方式改為成員函數(shù)類型的,成功解決了這個(gè)問題。
主要變動(dòng)如下:
可以看到,不同于上面( +
和 -
)重載中友元定義方式了。
函數(shù)定義如下:
2. 全部代碼
修改完之后,重新運(yùn)行,發(fā)現(xiàn)解決了問題,輸出結(jié)果如下:
全部源碼如下:
#include<iostream>
using namespace std;template <class T>
class Matrix
{typedef Matrix<T> Myt;
protected:T* m_pDatats; //數(shù)組int m_stRow, m_stCol; //行數(shù)和列數(shù)public://構(gòu)造函數(shù)Matrix(int stRow, int stCol);//復(fù)制構(gòu)造函數(shù)Matrix(const Myt& rhs);//析構(gòu)函數(shù)~Matrix();//矩陣初始化void Initialize(const T* rhs, int stRow, int stCol);// 取值函數(shù)T getValue(int row, int col);// 設(shè)置值函數(shù)void setValue(int row, int col, T value);// 矩陣運(yùn)算符相加friend Matrix<T> operator+<T>(const Matrix<T>& lhs, const Matrix<T>& rhs);// 矩陣運(yùn)算相減friend Matrix<T> operator-<T>(const Matrix<T>& lhs, const Matrix<T>& rhs);// 矩陣運(yùn)算相乘Matrix<T> operator* (Matrix<T>& rhs);
};//實(shí)現(xiàn)構(gòu)造函數(shù)
template<class T>
Matrix<T>::Matrix(int stRow, int stCol)
{m_stRow = stRow;m_stCol = stCol;m_pDatats = new T[stRow * stCol];
}// 實(shí)現(xiàn)復(fù)制構(gòu)造函數(shù)
template<class T>
Matrix<T>::Matrix(const Myt& rhs)
{m_pDatats = new T[rhs.m_stRow * rhs.m_stCol];m_stRow = rhs.m_stRow;m_stCol = rhs.m_stCol;Initialize(rhs.m_pDatats, rhs.m_stRow, rhs.m_stCol);
}//矩陣初始化的實(shí)現(xiàn)
template<class T>
void Matrix<T>::Initialize(const T* rhs, int stRow, int stCol)
{//用一維數(shù)組表示二位數(shù)組for (int i = 0; i < stRow * stCol; i++){m_pDatats[i] = rhs[i];}
}//實(shí)現(xiàn)析構(gòu)函數(shù)
template<class T>
Matrix<T>::~Matrix() {if (m_pDatats != nullptr) {delete[] m_pDatats;m_pDatats = nullptr;}
}// 獲取矩陣值
template<class T>
T Matrix<T>::getValue(int row, int col) {return m_pDatats[row * m_stRow + col];
}//設(shè)置值函數(shù)
template<class T>
void Matrix<T>::setValue(int row, int col, T value) {m_pDatats[row * m_stRow + col] = value;
}//矩陣相加的實(shí)現(xiàn)
template<class T>
Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs)
{if (lhs.m_stCol != rhs.m_stCol || lhs.m_stRow != rhs.m_stRow) {Matrix<T> tmp(0, 0);return tmp;}else {Matrix<T> tmp(rhs.m_stRow, rhs.m_stCol);for (int i = 0; i < rhs.m_stRow * rhs.m_stCol; i++) {tmp.m_pDatats[i] = lhs.m_pDatats[i] + rhs.m_pDatats[i];}return tmp;}
}
//矩陣相減的實(shí)現(xiàn)
template<class T>
Matrix<T> operator-(const Matrix<T>& lhs, const Matrix<T>& rhs)
{if (lhs.m_stCol != rhs.m_stCol || lhs.m_stRow != rhs.m_stRow) {Matrix<T> tmp(0, 0);return tmp;}else {Matrix<T> tmp(rhs.m_stRow, rhs.m_stCol);for (int i = 0; i < rhs.m_stRow * rhs.m_stCol; i++) {tmp.m_pDatats[i] = lhs.m_pDatats[i] - rhs.m_pDatats[i];}return tmp;}
}
//矩陣運(yùn)算相乘的實(shí)現(xiàn)
template<class T>
Matrix<T> Matrix<T>::operator* (Matrix<T>& rhs)
{if (m_stRow != rhs.m_stCol || m_stCol != rhs.m_stRow) {Matrix<T> tmp(0, 0);return tmp;}else {Matrix<T> tmp(m_stRow, rhs.m_stCol);for (int i = 0; i < tmp.m_stRow; i++) {for (int j = 0; j < tmp.m_stCol; j++) {int value = 0;for (int k = 0; k < m_stCol; k++) {value += getValue(i, k) * rhs.getValue(k, j);}tmp.setValue(i, j, value);}}return tmp;}
}
//主函數(shù)int main()
{int row = 3;int col = 3;Matrix<int> m1(row, col);int rhs[9] = { 1,2,3,4,5,6,7,8,9 };m1.Initialize(rhs, row, col);//輸出矩陣cout << "輸出的矩陣m1" << endl;for (int i = 0; i < row; i++){for (int j = 0; j < col; j++) {cout << m1.getValue(i, j) << " ";}cout << endl;}Matrix<int> m2(row, col);m2.Initialize(rhs, row, col);//輸出矩陣cout << "輸出的矩陣m2" << endl;for (int i = 0; i < row; i++){for (int j = 0; j < col; j++) {cout << m2.getValue(i, j) << " ";}cout << endl;}//兩矩陣相加Matrix<int> res = m1 + m2;cout << "兩矩陣輸出的結(jié)果矩陣為:" << endl;for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {cout << res.getValue(i, j) << " ";}cout << endl;}//兩矩陣相減Matrix<int> cut = m1 - m2;cout << "兩矩陣相減輸出的結(jié)果矩陣為:" << endl;for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {cout << cut.getValue(i, j) << " ";}cout << endl;}// 兩矩陣相乘Matrix<int> xc = m1 * m2;cout << "兩矩陣相減輸出的結(jié)果矩陣為:" << endl;for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {cout << xc.getValue(i, j) << " ";}cout << endl;}return 0;
}
四、總結(jié)
雖然解決了問題,但由于經(jīng)歷有限(而且其實(shí)是幫別人調(diào)的代碼,自己很少去寫模板的= =。),這個(gè)小bug我并沒有詳細(xì)的去追蹤他產(chǎn)生的根源。
具體產(chǎn)生的原因,也給出了兩個(gè)推測(cè):
- 在C++中,
*
運(yùn)算符是不能通過友元函數(shù)的方式進(jìn)行運(yùn)算符重載的。如果重載,只能采用成員函數(shù)的方式。 - 因?yàn)槌溯斎搿⑤敵鲋?。友元函?shù)在C++中其實(shí)并不提倡,因?yàn)樗茐牧祟惖姆庋b性。所以,我推測(cè)產(chǎn)生的原因可能是隨著
C++
標(biāo)準(zhǔn)的不斷迭代,逐漸在邊緣化友元函數(shù)。
以上就是我的兩點(diǎn)推測(cè),但沒有去詳細(xì)探究,如有紕漏,歡迎各位在評(píng)論區(qū)或者私信進(jìn)行指正,感謝!
the end……
關(guān)于C++ * 運(yùn)算符重載的一個(gè)小 bug 到這里就要結(jié)束啦~~到此既是緣分,歡迎您的點(diǎn)贊、評(píng)論、收藏!關(guān)注我,不迷路,我們下期再見!!
😘😘😘 我是Cherries,一位計(jì)算機(jī)科班在校大學(xué)生,寫博客用來記錄自己平時(shí)的所思所想!
💞💞💞 內(nèi)容繁雜,又才疏學(xué)淺,難免存在錯(cuò)誤,歡迎各位大佬的批評(píng)指正!
👋👋👋 我們相互交流,共同進(jìn)步!
注:本文由
非妃是公主
發(fā)布于https://blog.csdn.net/myf_666,轉(zhuǎn)載請(qǐng)務(wù)必標(biāo)明原文鏈接:https://blog.csdn.net/myf_666/article/details/129264092