建设干部学校网站首页做外单什么网站好
建设干部学校网站首页,做外单什么网站好,上海网站建设 普送,淘宝卖家中心网页版C 中的成员函数重载和 ref-qualifier#xff08;引用限定符#xff09;#xff0c;特别是在类似棋盘 ChessBoard 的场景下访问棋子时#xff0c;如何根据对象是 左值/右值 或 const/非 const 来返回不同类型的引用。
1⃣ 基本棋盘类访问函数
struct ChessBoard {ChessPie…C 中的成员函数重载和 ref-qualifier引用限定符特别是在类似棋盘ChessBoard的场景下访问棋子时如何根据对象是左值/右值或const/非 const来返回不同类型的引用。1⃣ 基本棋盘类访问函数structChessBoard{ChessPiece board[64];// 假设 8x8 棋盘// 左值对象非 constChessPieceat(std::size_t row,std::size_t col){std::coutlvalue non-const\n;returnboard[8*rowcol];}// 左值对象constChessPiececonstat(std::size_t row,std::size_t col)const{std::coutlvalue const\n;returnboard[8*rowcol];}// 右值对象非 constChessPieceat(std::size_t row,std::size_t col){std::coutrvalue non-const\n;returnstd::move(board[8*rowcol]);}// 右值对象constChessPiececonstat(std::size_t row,std::size_t col)const{std::coutrvalue const\n;returnstd::move(board[8*rowcol]);}};解释ref-qualifier/表示只能在左值对象上调用表示只能在右值对象上调用ChessBoard cb;cb.at(0,0);// 左值 → 调用 版本ChessBoard{}.at(0,0);// 右值 → 调用 版本const 修饰符const → 左值 constconst → 右值 constconstChessBoard ccb;ccb.at(0,0);// const 左值 → 调用 const 版本std::move(ccb).at(0,0);// const 右值 → 调用 const 版本返回值选择左值非 const → 返回ChessPiece可以修改棋子左值 const → 返回ChessPiece const只读右值非 const → 返回ChessPiece可以移动棋子右值 const → 返回ChessPiece const只读移动引用很少用2⃣ 为什么要用这种写法匹配对象的值类别左值/右值匹配对象的const 属性避免不必要的拷贝利用右值引用支持move semantics3⃣ C23 统一写法this autoC23 支持成员模板写法autoat(thisautoself,std::size_t row,std::size_t col){returnstd::forwarddecltype(self)(self).board[8*rowcol];}解释this auto self→self会根据调用对象的值类别自动推导为ChessBoard→ 左值ChessBoard const→ 左值 constChessBoard→ 右值ChessBoard const→ 右值 conststd::forwarddecltype(self)(self)→ 完美转发保证左值返回左值引用右值返回右值引用返回类型auto→ 完美引用自动匹配值类别和 const 性质4⃣ 对应数学表示假设棋盘数组b o a r d [ b 0 , 0 , b 0 , 1 , . . . , b 7 , 7 ] board [b_{0,0}, b_{0,1}, ..., b_{7,7}]board[b0,0,b0,1,...,b7,7]行列访问公式b o a r d [ r o w ∗ 8 c o l ] board[row*8 col]board[row∗8col]返回引用类型根据对象类别at ( r o w , c o l ) { C h e s s P i e c e 左值非 const c o n s t C h e s s P i e c e 左值 const C h e s s P i e c e 右值非 const c o n s t C h e s s P i e c e 右值 const \text{at}(row,col) \begin{cases} ChessPiece\ \text{左值非 const} \\ const\ ChessPiece\ \text{左值 const} \\ ChessPiece\\ \text{右值非 const} \\ const\ ChessPiece\\ \text{右值 const} \end{cases}at(row,col)⎩⎨⎧ChessPiececonstChessPieceChessPiececonstChessPiece左值非const左值const右值非const右值const5⃣ 使用示例ChessBoard cb;constChessBoard ccb;cb.at(0,0);// lvalue non-constccb.at(0,0);// lvalue conststd::move(cb).at(0,0);// rvalue non-conststd::move(ccb).at(0,0);// rvalue const// C23 版本cb.at(1,1);// 自动推导 完美转发std::move(cb).at(1,1);// 自动推导 完美转发控制台输出lvalue non-const lvalue const rvalue non-const rvalue const6⃣ 总结ref-qualifier(/) 可以根据对象值类别重载成员函数const决定是否可以修改对象C23 的this autoauto返回类型 → 自动推导值类别 const 完美引用代码简洁、可维护访问棋盘公式统一board[row*8 col]https://godbolt.org/z/Po9h58cjd1⃣ 数据结构定义structChessPiece{std::string name;};定义了一个ChessPiece结构体表示棋子。里面只有一个成员name用于存储棋子的名称比如 “Pawn”, “Knight” 等。structChessBoard{ChessPiece board[64];// 8x8 棋盘ChessBoard是棋盘类用一个一维数组board[64]存储棋子。8x8 的棋盘可以通过索引计算访问index 8 × row col \text{index} 8 \times \text{row} \text{col}index8×rowcol2⃣ 四种成员函数重载传统写法C11/14/17 支持ref-qualified member functions可以根据对象的左值/右值和 const 修饰选择不同的函数。// 左值非 constChessPieceat(std::size_t row,std::size_t col){std::coutlvalue non-const\n;returnboard[8*rowcol];}表示只能作用于左值对象。返回可修改的引用可以修改棋盘内容。调用例cb.at(0,0)// 左值 constChessPiececonstat(std::size_t row,std::size_t col)const{std::coutlvalue const\n;returnboard[8*rowcol];}const表示只能作用于 const 左值。返回const 引用不可修改棋子。调用例ccb.at(0,0)// 右值非 constChessPieceat(std::size_t row,std::size_t col){std::coutrvalue non-const\n;returnstd::move(board[8*rowcol]);}表示只能作用于右值对象。返回右值引用允许移动语义。调用例std::move(cb).at(0,1)// 右值 constChessPiececonstat(std::size_t row,std::size_t col)const{std::coutrvalue const\n;returnstd::move(board[8*rowcol]);}const表示只能作用于右值且 const 对象。返回const rvalue 引用可以移动但不可修改内容。调用例std::move(ccb).at(0,1)✓ 总结左值/右值 const 修饰 形成 4 种组合。可以精确控制函数调用和返回类型提高效率。特别适合带移动语义的类型如std::string、std::vector。3⃣ C23this auto统一写法autoat23(thisautoself,std::size_t row,std::size_t col){std::coutC23 this auto version\n;returnstd::forwarddecltype(self)(self).board[8*rowcol];}this auto self是C23 新特性把this当作普通参数。优势无需写四个重载函数。自动根据调用对象类型左值/右值、const/非 const完美转发。std::forwarddecltype(self)(self)保证左值调用 → 返回引用右值调用 → 返回右值引用调用示例cb.at23(1,0);// 左值非 constccb.at23(1,0);// 左值 conststd::move(cb).at23(1,1);// 右值非 conststd::move(ccb).at23(1,1);// 右值 const所有情况都只需要一个函数即可处理。4⃣ 主函数分析ChessBoard cb;constChessBoard ccb;cb.board[0].namePawn;cb.board[1].nameKnight;创建普通棋盘cb和 const 棋盘ccb。给cb设置棋子名称。测试四种重载和 C23 新特性。cb.at(0,0);// 输出: lvalue non-constccb.at(0,0);// 输出: lvalue conststd::move(cb).at(0,1);// 输出: rvalue non-conststd::move(ccb).at(0,1);// 输出: rvalue const四种传统重载清晰展示调用规则。C23 版本cb.at23(1,0);ccb.at23(1,0);std::move(cb).at23(1,1);std::move(ccb).at23(1,1);统一函数 → 自动完美转发。输出都是C23 this auto version5⃣ 代码理解总结特性调用对象返回类型说明ChessPiece at() 左值非 const左值引用可修改棋子const ChessPiece at() const左值 constconst 左值引用只读棋子ChessPiece at() 右值非 const右值引用可移动棋子const ChessPiece at() const右值 constconst 右值引用可移动但只读棋子auto at23(this auto)任意对象完美转发引用C23 统一写法自动适应左值/右值、const数学公式表示下标计算board[row][col] board [ 8 ⋅ r o w c o l ] \text{board[row][col]} \text{board}[8 \cdot row col]board[row][col]board[8⋅rowcol]完美转发公式C23return type decltype(auto) of s t d : : f o r w a r d d e c l t y p e ( s e l f ) ( s e l f ) . b o a r d [ i n d e x ] \text{return type} \text{decltype(auto)}\ \text{of}\ std::forwarddecltype(self)(self).board[index]return typedecltype(auto)ofstd::forwarddecltype(self)(self).board[index]