为什么要两次? 这2行,为什么这样做?一个人够吗?
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 //
答案 0 :(得分:10)
一个是const
,另一个不是。
不同之处在于,当您对const
进行Array2D
引用时,您只能调用标记为const
的成员函数。在这种情况下,这意味着第二个版本,它必须返回对它所拥有的元素的const
引用。
如果您有非const
引用,则第二个版本意味着您无法使用operator()
对Array2D
进行任何更改。
如果你看一下像std::vector
这样的标准库容器,你会发现它们做同样的事情。您可以从iterator
获得begin()
,从const_iterator
获得begin() const
。
答案 1 :(得分:2)
第一个非常量版本返回可以修改的引用。如果你有一个常量对象,你仍然希望能够至少读取该值,所以你必须提供第二个常量版本。
答案 2 :(得分:2)
两个()运算符不一样。 inline T& operator() (int row, int col);
返回一个允许修改返回值的引用。 const inline T& operator() (int row, int col) const
返回一个不允许修改返回值的引用。此外,如果调用对象是const alg::Array2D&
,那么它只能使用const operator();
。因此,为了允许Array2D类的用户正确使用const对象。最佳实践是为operator()实现两个签名。
答案 3 :(得分:0)
你可以有一个函数void make_something (const Array2D<char> &input, Array2D<char> &output)
。此函数允许输入不变,对其进行一些操作,并将结果写入输出。只有存在const运算符时才能读取输入。
答案 4 :(得分:0)
inline T& operator() (int row, int col) { return this->m_data[row*NC + col]; }
返回m_data[row * NC + col]
中数据的非const引用,这意味着我可以
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]; }
这允许我向外传播constness:
void myFunc(const Object& obj) /* I'm only going to look */
{
const auto& ref = obj(x, y);
std::cout << x << ',' << y << " = " << ref << '\n';
}