如何在构造函数中初始化的函数中修改对象大小的2D向量
C++ how to modify a 2D vector of objects size in a function initialized in the constructor?
因为我是意大利人,所以函数名是意大利语,但很容易理解: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);
}
}
与代码检查相关的注意事项:您也可以非常容易地调整内部元素的大小,使用resize-overload,它带有一个附加参数:(*immag)[r][c]=imm; }
(*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; } }
- 在C++中将对象添加到 2D 矢量
- 使用 c++ 将 2d CAD 对象转换为 TIFF 格式
- 我有一个 Qt 对象的 2d 数组,我已经用值播种了这些对象。如何访问数组中特定对象的值并更改它们?
- 类对象指针C 的2D向量
- 如何在C 2D向量中找到对象(而不是int)的位置
- 将每个对象渲染到空间中,并在3D场景上渲染2D场景
- 如何在C 中打印一个对象的2D向量
- 无法用2D矢量成员引用对象
- 如何使用结构在 2d 数组中移动玩家对象
- 创建一个动态2D数组来存储类对象
- OPENCV(C ) - 从已知的3D对象和相机位置计算图像的2D坐标
- (C++)用于实例化新对象并将其分配给指向相同对象类型的指针的 2D 向量的语法
- 无法使用 opengl 正确旋转 2D 对象
- C 2D对象的动态数组
- 如何将对象分配到2D矢量no Match oterator =
- C 中的对象的2D数组
- 如何将2D向量中的对象设置为空指针[C ]
- 通过引用调用类对象的 2D 数组
- 如何快速绘制10000 2D图形对象
- 如何将2d数组对象传递给c++中的函数