Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么要编写两个()运算符_C++ - Fatal编程技术网

C++ 为什么要编写两个()运算符

C++ 为什么要编写两个()运算符,c++,C++,为什么要做两次? 这两行,为什么会这样?一个够了吗 inline T& operator() (int row, int col) { return this->m_data[row*NC + col]; } const inline T& operator() (int row, int col) const { return this->m_data[row*NC + col]; } 多谢各位 * * 2-DIMENSIONAL ARRAY * * S

为什么要做两次? 这两行,为什么会这样?一个够了吗

inline T& operator() (int row, int col) { return this->m_data[row*NC + col]; }

const inline T& operator() (int row, int col) const { return this->m_data[row*NC + col]; }
多谢各位

 *
 * 2-DIMENSIONAL ARRAY
 *
 * Simulated by 1-dimension array.
 ******************************************************************************/

#ifndef __2D_ARRAY_H__
#define __2D_ARRAY_H__
#include <stdint.h>
#include <stdlib.h>

namespace alg {
    /**
     * 2D Array definition
     */
    template <typename T=char>
        class Array2D {
            private:
                uint32_t NR;        // num of rows
                uint32_t NC;        // num of columns
                T * m_data;         // the place where the array resides.

            public:
                /**
                 * construct an array of size [nrow,col]
                 */
                Array2D(uint32_t nrow, uint32_t ncol) {
                    NR = nrow;
                    NC = ncol;  
                    m_data = new T[nrow*ncol];
                }

                /**
                 * destructor
                 */ 
                ~Array2D() {
                    delete [] m_data;
                }

            private:
                Array2D(const Array2D&);    
                Array2D& operator=(const Array2D&); 

            public:

                /**
                 * return number of rows of this array
                 */
                inline const uint32_t row() const { return NR; }
                /**
                 * return number of columns of this array
                 */
                inline const uint32_t col() const { return NC; }

                /**
                 * return the value by the given (row, col);
                 */
                inline T& operator() (int row, int col) { return this->m_data[row*NC + col]; }
                const inline T& operator() (int row, int col) const { return this->m_data[row*NC + col]; }

                inline T* operator[] (int row) { return &(m_data[row * NC]); }
                inline const T* operator[] (int row) const { return &(m_data[row * NC]); }

                /**
                 * clear the array by a given value
                 */
                void clear(const T & value) {
                    for(uint32_t i=0; i<NR*NC;i++){
                        m_data[i] = value;
                    }
                }
        };
}

#endif //
*
*二维阵列
*
*用一维阵列模拟。
******************************************************************************/
#ifndef uu 2D u阵列H__
#定义二维数组__
#包括
#包括
名称空间alg{
/**
*二维数组定义
*/
模板
类数组2d{
私人:
uint32\u t NR;//行数
uint32\u t NC;//列数
T*m_data;//数组所在的位置。
公众:
/**
*构造一个大小为[nrow,col]的数组
*/
阵列2d(uint32\u t nrow,uint32\u t ncol){
NR=nrow;
NC=ncol;
m_数据=新的T[nrow*ncol];
}
/**
*析构函数
*/ 
~Array2D(){
删除[]m_数据;
}
私人:
阵列2d(常数阵列2d&);
Array2D&运算符=(常量Array2D&);
公众:
/**
*返回此数组的行数
*/
内联常量uint32_t row()常量{return NR;}
/**
*返回此数组的列数
*/
内联常量uint32\u t col()常量{return NC;}
/**
*返回给定值(行、列);
*/
内联T运算符()(int行,int列){返回此->m_数据[row*NC+col];}
const inline T&operator()(int行,int列)const{返回此->m_数据[row*NC+col];}
内联T*运算符[](int行){return&(m_data[row*NC]);}
内联常量T*运算符[](int行)常量{return&(m_data[row*NC]);}
/**
*按给定值清除数组
*/
空隙清除(常数T和值){

对于(uint32_t i=0;i一个是
const
,另一个不是

不同之处在于,当您对
Array2D
const
引用时,您只允许调用标记为
const
的成员函数。在这种情况下,这意味着第二个版本,其中它必须返回一个
const
引用到它所持有的元素

但是,如果您有一个非
const
引用,那么第二个版本意味着您不能使用
operator()
Array2D
进行任何更改


如果您查看标准库容器,如
std::vector
,您将看到它们做了相同的事情。您可以从
begin()
获得
iterator
,从
begin()获得
const\u iterator
const

第一个非常量版本返回一个可以修改的引用。如果您有一个常量对象,您仍然希望至少能够读取该值,因此必须提供第二个常量版本。

这两个()运算符不相同。
内联T&operator()(int行,int列);
返回一个允许修改返回值的引用。
const inline T&operator()(int row,int col)const
返回一个不允许修改返回值的引用。另外,如果调用对象是
const alg::Array2D&
,则它只能使用
const运算符()因此,为了允许Array2D类的用户正确使用const对象,最好是为操作符()实现两个签名。

您可以使用函数
void make\u something(const Array2D&input,Array2D&output)
。此函数允许输入保持不变,使用它进行一些操作,并将结果写入输出。只有在同时存在常量运算符的情况下,才可以读取输入

inline T& operator() (int row, int col) { return this->m_data[row*NC + col]; }
返回对
m_data[row*NC+col]
中数据的非常量引用,这意味着我可以

auto& ref = obj(x, y);
ref = BAD_DATA;
而且你的对象无法阻止我。const的
变体可以防止这种情况,并且可以作为const进行指纹识别,因为它对对象没有副作用

inline const T& operator() (int row, int col) const { return this->m_data[row*NC + col]; }
这允许我向外传播常数:

void myFunc(const Object& obj) /* I'm only going to look */
{
    const auto& ref = obj(x, y);
    std::cout << x << ',' << y << " = " << ref << '\n';
}
void myFunc(const Object&obj)/*我只想看看*/
{
常数auto&ref=obj(x,y);

std::可以说常量版本是一个getter而非常量版本是一个setter吗?@user2672165不,它们都是getter。一个提供常量引用,另一个提供常规引用……但是当然,非常量版本可以用来修改数组的内容。因此,它的工作方式与setter类似。@Adam:当然。但是如果您不想更改值,为什么要使用非常量版本?@user2672165如果您有选择的话,那就由您决定。我想说的是,它们都有一个元素的引用。请注意,包含两个连续下划线的名称(
\uu 2D\u ARRAY\u H\uu
)以下划线和大写字母开头的名称保留给实现。不要使用它们。@Pete Becker真的,你能告诉我如何引用吗?17.6.4.3.2[global.names]/1:“……每个名称都包含一个双下划线或以下划线和大写字母开头(2.12)保留给实现以供任何使用……”