C++;一个函数中的setter/getter? 我一直在做C++课程,其中一个家庭作业要求实现一个具有私有成员的RoSs*、CLSSI、DATAAI的图像类。其中,数据是长度为行X列的向量。他们要求实现一种方法,通过这种方法,您可以访问给定行和列的数据值,这很好。但是,他们也希望能够为该位置分配一个值,如下所示: int val = image.at(row, col); Image.at(row, col) = 255;

C++;一个函数中的setter/getter? 我一直在做C++课程,其中一个家庭作业要求实现一个具有私有成员的RoSs*、CLSSI、DATAAI的图像类。其中,数据是长度为行X列的向量。他们要求实现一种方法,通过这种方法,您可以访问给定行和列的数据值,这很好。但是,他们也希望能够为该位置分配一个值,如下所示: int val = image.at(row, col); Image.at(row, col) = 255;,c++,C++,我觉得很奇怪,如果我返回了对数据中条目的引用,上述功能是否有效?我觉得你不应该允许图像。at(row,col)=255;由于这破坏了数据的封装是,请声明返回引用的方法 int & at(int row, int col) {return data[row * width + col];} 将新值赋给输出将重写数据成员内部某个位置分配的内存中的数据,因为引用指向该位置。是声明返回引用的方法 int & at(int row, int col) {return data[row *

我觉得很奇怪,如果我返回了对数据中条目的引用,上述功能是否有效?我觉得你不应该允许图像。at(row,col)=255;由于这破坏了数据的封装

是,请声明返回引用的方法

int & at(int row, int col) {return data[row * width + col];}

将新值赋给输出将重写
数据
成员内部某个位置分配的内存中的数据,因为引用指向该位置。

是声明返回引用的方法

int & at(int row, int col) {return data[row * width + col];}

将新值赋给输出将重写
data
成员中分配的内存中的数据,因为引用指向该成员。

以这种方式返回对某些内部数据的引用是非常合理的

如果你非常担心,你可以返回一个包装器对象,它只允许对单个像素进行操作,但这可能太过分了

然而,提供一个const-correct函数并不过分。如果您有一个const image对象并希望从中读取像素,这一点很重要

所以,你可能会有这样的想法:

class Image
{
public:
    Image()
        : mWidth(0)
        , mHeight(0)
    {}

    Image(int width, int height, const Pixel& color = {})
        : mWidth(width)
        , mHeight(height)
        , mBuffer(width * height, color)
    {}

    Pixel& at(int row, int col)
    {
        return mBuffer.at(row * mWidth + col);
    }

    const Pixel& at(int row, int col) const
    {
        return mBuffer.at(row * mWidth + col);
    }

private:
    int mWidth, mHeight;
    std::vector<Pixel> mBuffer;
};
类图像
{
公众:
图像()
:mWidth(0)
,mHeight(0)
{}
图像(整数宽度、整数高度、常量像素和颜色={})
:mWidth(宽度)
,mHeight(身高)
,mBuffer(宽度*高度,颜色)
{}
像素和at(整数行,整数列)
{
返回mBuffer.at(行*宽+列);
}
常量像素和at(整数行,整数列)常量
{
返回mBuffer.at(行*宽+列);
}
私人:
内特米维兹,米维思;
std::向量mBuffer;
};

注意,我在这里使用了
Pixel
来显示返回常量引用的更通用形式。当然,如果您只使用整数,那么const版本根本不需要返回引用——它可以只返回
int
,而non-const函数仍将返回
int&
,以这种方式返回对某些内部数据的引用是非常合理的

如果你非常担心,你可以返回一个包装器对象,它只允许对单个像素进行操作,但这可能太过分了

然而,提供一个const-correct函数并不过分。如果您有一个const image对象并希望从中读取像素,这一点很重要

所以,你可能会有这样的想法:

class Image
{
public:
    Image()
        : mWidth(0)
        , mHeight(0)
    {}

    Image(int width, int height, const Pixel& color = {})
        : mWidth(width)
        , mHeight(height)
        , mBuffer(width * height, color)
    {}

    Pixel& at(int row, int col)
    {
        return mBuffer.at(row * mWidth + col);
    }

    const Pixel& at(int row, int col) const
    {
        return mBuffer.at(row * mWidth + col);
    }

private:
    int mWidth, mHeight;
    std::vector<Pixel> mBuffer;
};
类图像
{
公众:
图像()
:mWidth(0)
,mHeight(0)
{}
图像(整数宽度、整数高度、常量像素和颜色={})
:mWidth(宽度)
,mHeight(身高)
,mBuffer(宽度*高度,颜色)
{}
像素和at(整数行,整数列)
{
返回mBuffer.at(行*宽+列);
}
常量像素和at(整数行,整数列)常量
{
返回mBuffer.at(行*宽+列);
}
私人:
内特米维兹,米维思;
std::向量mBuffer;
};
注意,我在这里使用了
Pixel
来显示返回常量引用的更通用形式。当然,如果只使用整数,const版本根本不需要返回引用——它可以只返回
int
,而non-const函数仍然返回
int&
,这与eg类似

基于这是大多数标准容器和迭代器的工作方式,我认为这很好。请记住
const
的正确性,并提供const访问器。

这与eg类似


基于这是大多数标准容器和迭代器的工作方式,我认为这很好。请记住
const
正确性,并提供const访问器。

容器类用于访问存储在其中的对象,否则,这样的容器有什么意义?破坏封装。取决于上下文。在这种情况下,没有。我想说这比定义单独的
get()
set()
方法要好得多,它们以相同的方式破坏封装。容器类旨在访问存储在其中的对象,否则这样的容器有什么意义?破坏封装。取决于上下文。在这种情况下不是。我想说这比定义分开的
get()
set()
方法要好得多,它们以同样的方式破坏封装。常量访问器是否与paddy的答案中的方法一样?当类的用户说,const Pixel=Image.at()等时,这个方法是否只返回一个常量。如果他们不使用const,它将使用Pixel&at()方法?@Cr1064 const指的是对象本身,而不是它返回的内容。如果是这样,编译器如何知道哪个at()呢要使用的方法?常量访问器是否与paddy答案中的方法相同?当类的用户说const Pixel=Image.at()等时,该方法是否只返回一个常量。如果他们不使用const,它将使用Pixel&at()方法?@Cr1064 const指的是对象本身,而不是它返回的内容。如果是这样,编译器如何知道使用哪个at()方法?