如何在构造函数中初始化的函数中修改对象大小的2D向量

C++ how to modify a 2D vector of objects size in a function initialized in the constructor?

本文关键字:对象 2D 向量 修改 函数 构造函数 初始化      更新时间:2023-10-16

因为我是意大利人,所以函数名是意大利语,但很容易理解:imagine =image, inserisci=insert, altezza=height, larghezza=width,mosaico =mosaic, right =rows, colonne=columns。

所以这个程序有两个类:一个带有属性的图像和一个马赛克,它包含n个图像,这是通过一个2D向量obj image(想象)来表示的。2D向量必须在构造函数中初始化为r行和c列,然后使用inserisci(插入/添加)函数来增加其维度。然后,如果传入插入函数的元素有更多的行/列,则插入函数必须添加所需的行和列才能插入该元素。

问题是,即使我使用指针/引用,每次我试图插入一个大小大于构造函数中初始化的元素时,它给了我一个错误,这意味着我在插入函数中修改的2D向量并没有真正编辑…(当我插入:m2时,看看main。Inserisci (i4,4,4, &m2. imagini),因为4行>行的初始大小,列的大小相同,给我一个运行错误…)希望这是清楚的。这是我的代码:

#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
class Immagine{
private:
        string nome;
public:
        int altezza;
        int larghezza;
        Immagine(string,int,int);
        string toString();
};
Immagine::Immagine(string n, int a, int l){
    nome = n;
    altezza = a;
    larghezza= l;
}
string Immagine::toString(){ 
    return nome;
        }
class Mosaico{
public:
    Mosaico(int, int,Immagine,vector< vector<Immagine> >*);
    int getRighe();
    int getColonne();
    string getImmagine(int,int);
    bool exist(int, int);
    Immagine getIm(int,int);
    void inserisci(Immagine,int,int,vector< vector<Immagine> >*);
    vector< vector<Immagine> > immagini;
    vector< vector<Immagine> >* aPointer= &immagini;
};
    Mosaico::Mosaico(int r, int c,Immagine imm, vector< vector<Immagine> >* immag ){
    (*immag).resize(r);
    for(int i=0; i<(*immag).size(); i++)
        for(int j=0; j<c; j++)
            (*immag)[i].insert((*immag)[i].begin()+j,imm);
}   
bool Mosaico::exist(int r, int c){
    for(int i = 0; i < getRighe(); i++){
        for(int j=0; j<getColonne(); j++){
            if(i==r && j==c && immagini[r][c].toString()!= " "){
                return true;
            }
        }
    }     
    return false;
}
int Mosaico::getRighe(){
    return immagini.size();
    }
int Mosaico::getColonne(){
    return immagini[1].size();
    }
string Mosaico::getImmagine(int r, int c){
    if(exist(r,c))
    return immagini[r][c].toString();
    }
Immagine Mosaico::getIm(int r, int c){
    return immagini[r][c];
}

void Mosaico::inserisci(Immagine imm,int r, int c, vector< vector<Immagine> >* immag){
        if(r<(*immag).size() && c<(*immag)[0].size()){
        (*immag)[r][c]=imm;
        }
        else if(r>=(*immag).size() && c>=(*immag)[0].size()){
            (*immag).resize(r);
            for(int i=0; i<r; i++){
                for(int j=(*immag)[0].size(); j<c; j++){
                    (*immag)[i].insert((*immag)[i].begin()+j, imm);
                }
            }
            (*immag)[r][c]=imm;
            }
        else if(r>=(*immag).size() && c<(*immag)[0].size()){
            (*immag).resize(r);
            (*immag)[r][c]=imm;
        }
    else if(r<(*immag).size() && c>=(*immag)[0].size()){
            for(int i=0; i<(*immag).size(); i++){
                for(int j=(*immag)[0].size(); j<c; j++){
                    (*immag)[i].insert((*immag)[i].begin()+j, imm);
                }
            }
            (*immag)[r][c]=imm;
            }
}
int main() {
    Immagine i1 ("I01",300,200);
    Immagine i2 ("I02",300,400);
    Immagine i3 ("I03",400,200);
    Immagine i4 ("I04",400,400);
    cout << "Creo un mosaico 2x2 con quattro immagini" <<endl;
    Mosaico m2(2,2,i1,&m2.immagini) ;
    cout<<m2.getRighe()<<endl;
    cout<<m2.getColonne()<<endl;
    for (int i=0; i < m2.getRighe(); i++) {
        for (int j=0; j < m2.getColonne(); j++){
            //if(m1.exist(i,j))
            cout<<m2.getImmagine(i,j);
        }
        cout<<endl;
    }
    m2.inserisci(i1, 0, 0, &m2.immagini);
    m2.inserisci(i2, 0, 1, &m2.immagini);
    m2.inserisci(i3, 1, 0, &m2.immagini);
    m2.inserisci(i4, 4, 4, &m2.immagini); //HERE IS WHERE I GET THE ERROR
    cout <<"Stampa mosaico: "<<endl;
    for (int i=0; i < m2.getRighe(); i++) {
        for (int j=0; j < m2.getColonne(); j++){
            cout<<m2.getImmagine(i,j);
        }
        cout<<endl;
    }
}
顺便说一下,这是一个Java练习,我试着用c++来做。提前感谢!

在讨论这些问题的细节之前,让我先声明一下,在代码中有很多事情是我想以不同的方式处理的。最显著的是,我可能会使用扁平的vector<Image>来存储,而不是vector<vector<..>>。但在我看来,这样的事情更适合于CodeReview(一旦代码正常工作)。


OP代码中最大的问题在于inserisci函数的实现:

void Mosaico::inserisci(Immagine imm,int r, int c,
                        vector< vector<Immagine> >* immag) {
    if(r < (*immag).size() && c < (*immag)[0].size()){
        (*immag)[r][c]=imm;
    }

这部分很好,如果我们假设(*immag)[i].size()对于[0, (*immag).size())中的所有i都是相同的。让我们称这个假设为a。[x, y)符号表示半右开区间(x在该区间内,y不在)。请注意,您可以将(*e).m替换为e->m,我将在下面这样做。

假设A是一个类不变量:在每个成员函数之后(析构函数除外),这个类不变量必须保持不变。继续inserisci函数:

    else if(r>=(*immag).size() && c>=(*immag)[0].size()){
        (*immag).resize(r);

*immag向量现在有r元素。如果您想要访问r元素,那么是不够的,因为索引从0开始。你需要至少有r+1个元素。将上面的resize替换为:

        int newRowCount = r+1;
        (*immag).resize(newRowCount);

继续OP的功能:

        for(int i=0; i<r; i++){

这有相同的off-by- 1错误:将r替换为newRowCount,或者简单地替换为immag->size()

         for(int i=0; i<immag->size(); i++){

继续OP的功能:

            for(int j=(*immag)[0].size(); j<c; j++){
                (*immag)[i].insert((*immag)[i].begin()+j, imm);
            }
        }

有了上面的resize,我们在immag向量中添加了newRowCount - immag->size()个新元素。这些元素是大小为0的向量。为了能够访问这样一个向量的第c个元素,我们需要向其添加至少c+1个元素。

(*immag)[0].size()的值在外循环的第一次迭代之后改变,使得i[1, newRowCount)中的(*immag)[i]元素的(*immag)[0].size() == c。此代码不会向这些行添加任何新列。一个简单的修复方法是:

            int newColumnCount = c+1;
            for(int j=(*immag)[i].size(); j < newColumnCount; j++){
                (*immag)[i].insert((*immag)[i].begin()+j, imm);
            }
        }
        (*immag)[r][c]=imm;
    }
与代码检查相关的注意事项:您也可以非常容易地调整内部元素的大小,使用resize-overload,它带有一个附加参数:
(*immag)[i].resize(newColumnCount, imm);

继续OP:

    else if(r>=(*immag).size() && c<(*immag)[0].size()){
        (*immag).resize(r);

这又遇到了同样的off-by- 1错误。您需要至少有r+1个元素才能访问以下

中的r个元素
        (*immag)[r][c]=imm;
    }

在下面的代码段中,出现了与第二个分支相同的问题(即(*immag)[0].size()而不是引用当前元素的大小,j < c而不是j < newColumnCount)。

    else if(r<(*immag).size() && c>=(*immag)[0].size()){
        for(int i=0; i<(*immag).size(); i++){
            for(int j=(*immag)[0].size(); j<c; j++){
                (*immag)[i].insert((*immag)[i].begin()+j, imm);
            }
        }
        (*immag)[r][c]=imm;
    }
}