【问题标题】:Difficulty with mutation involving classes涉及类的突变困难
【发布时间】:2017-03-12 04:29:23
【问题描述】:

我有一个班级characterData 和一个此类列表:

class characterData {
    private:
        vector<vector<int> > pixelData;
        int area;
    public:
        void setPix(vector<vector<int> > in) {
            pixelData = in;
            area = in.size() * in[0].size();
        }
        vector<vector<int> > getPix() {
            return pixelData;
        }
        int getArea() {
            return area;
        }
};

list<characterData> listChars;

我正在尝试用其他方法改变pixelData,但一直遇到问题。我有一个方法可以对pixelData 起作用:

void processHandler(list<characterData> &inList) {
    while (!inList.empty()) {
        normalize(inList.front().getPix());
        inList.pop_front();
    }
}

void normalize(vector<vector<int> > &input) {
    if (input.size() > input[0].size()) {
        affixRows(input, input.size() - input[0].size());
    } else if (input.size() > input[0].size()) {
        affixCols(input, input[0].size() - input.size());
    }
}

void affixRows(vector<vector<int>> &input, int dimDiff) {
    vector<vector<int>> temp(input.size(), vector<int>(input[0].size() + dimDiff));
    for (unsigned int i = 0; i < temp[0].size(); i++) {
        for (unsigned int j = 0; j < temp.size(); j++) {
            if (i < (unsigned int)dimDiff / 2) {
                temp[j][i] = 255;
            }
            else if (i < input[0].size() + (int)dimDiff / 2) {
                temp[j][i] = input[j][i - (int)dimDiff / 2];
            }
            else {
                temp[j][i] = 255;
            }
        }
    }
    input = temp; // point of mutation
}

void affixCols(vector<vector<int>> &input, int dimDiff) {
    vector<vector<int>> temp(input.size() + dimDiff, vector<int>(input[0].size()));
    for (unsigned int i = 0; i < temp[0].size(); i++) {
        for (unsigned int j = 0; j < temp.size(); j++) {
            if (j < (unsigned int)dimDiff / 2) {
                temp[j][i] = 255;
            }
            else if (j < input.size() + (int)dimDiff / 2) {
                temp[j][i] = input[j - (int)dimDiff / 2][i];
            }
            else {
                temp[j][i] = 255;
            }
        }
    }
    input = temp; // point of mutation
}

我收到以下错误:

error: invalid initialization of non-const reference of type 'std::vector<std::vector<int> >&' from an rvalue of type 'std::vector<std::vector<int> >'
normalize(inList.front().getPix());
-------------------------------^--

如果不是:

normalize(inList.front().getPix());

我制作了一个临时向量并使用它,它没有错误。

vector<vector<int> > temp = inList.front().getPix();
normalize(temp);

但这不会实现我想要的,它正在改变characterDatapixelData。为什么不能直接访问pixelData进行变异?

【问题讨论】:

    标签: c++ pointers mutators


    【解决方案1】:

    您混淆了指针和引用的使用。

    在函数void processHandler(list&lt;characterData&gt; *inList)中,inList是一个指针,但函数内的代码使用它作为引用。

    while (!inList.empty())
    {
        normalize(inList.front().getPix());
        inList.pop_front();
    }
    

    需要将inList 视为指针。所以用inList-&gt;替换inList.

    while (!inList->empty())
    {
        normalize(inList->front().getPix());
        inList->pop_front();
    }
    

    这将产生第二个问题,因为characterData::getPix() 按值返回。但是normalize() 需要一个引用(因此编译器会抱怨类似于将引用传递给一个临时对象 - 临时对象包含getPix() 返回的值,这将是pixelData 的副本)。相反,要以这种方式使用它,getPix() 需要返回一个引用。

    vector<vector<int> > &getPix() {return pixelData;}    // note the ampersand
    

    这解决了您的问题。更一般地说,您的设计存在致命缺陷 - characterData 的成员函数提供对任何 private 成员的直接访问(通过指针或引用)是一个坏主意,因为它允许任何代码更改该成员。如果你打算这样做,你不妨让成员public而不是private

    您需要为characterData 提供成员函数,允许调用者请求更改private 成员函数(例如添加元素)。如果您选择,这些功能可以忽略此类请求。更重要的是,它们允许您的类及其成员函数共同确保数据始终处于有效状态。如果调用者可以进行任意更改,这是不可能的。

    【讨论】:

      【解决方案2】:

      您的 getPix 方法返回一个临时对象。

      vector<vector<int> > getPix() {
      ~~~~~~~~~~~~~~~~~~~~
                  return pixelData;
              }
      

      可能希望通过引用返回它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-02-19
        • 1970-01-01
        • 1970-01-01
        • 2021-10-30
        • 1970-01-01
        • 1970-01-01
        • 2012-04-10
        相关资源
        最近更新 更多