我有一个班级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);
但是这并没有实现我想要的,这正在改变pixelData
的{{1}}。为什么我不能直接访问characterData
以进行突变?
答案 0 :(得分:1)
您的getPix
方法返回一个临时对象。
vector<vector<int> > getPix() {
~~~~~~~~~~~~~~~~~~~~
return pixelData;
}
你可能希望通过引用返回它。
答案 1 :(得分:1)
你混淆了指针和引用的使用。
在函数void processHandler(list<characterData> *inList)
中,inList
是指针,但函数中的代码将其用作参考。
while (!inList.empty())
{
normalize(inList.front().getPix());
inList.pop_front();
}
需要将inList
视为指针。因此,请将inList.
替换为inList->
。
while (!inList->empty())
{
normalize(inList->front().getPix());
inList->pop_front();
}
这会产生第二个问题,因为characterData::getPix()
按值返回。但是normalize()
需要一个引用(因此编译器会抱怨类似于将引用传递给临时的东西 - 临时保存getPix()
返回的值,这将是{{1}的副本})。相反,要以这种方式使用它,pixelData
需要返回引用。
getPix()
这解决了您提出的问题。更一般地说,您的设计存在致命缺陷 - vector<vector<int> > &getPix() {return pixelData;} // note the ampersand
的成员函数提供对任何characterData
成员的直接访问(通过指针或引用)是一个坏主意,因为它允许任何代码更改该成员。如果您打算这样做,您也可以让成员private
而不是public
。
您需要提供private
的成员函数,以允许调用者请求characterData
成员函数的更改(例如添加元素)。这些功能可以 - 如果您选择 - 忽略此类请求。更重要的是,它们允许您的类及其成员函数共同确保数据始终处于有效状态。如果调用者可以进行任意更改,则无法进行此操作。