C++ 创建对象C++;
我有一个类,它包含一个浮点型缓冲区,指向一个RGB值数组。缓冲区是正确创建和存储的,但是当我通过函数将该类的实例返回到main()时,缓冲区的内存是不可读的。这是初级课程:C++ 创建对象C++;,c++,buffer,typedef,C++,Buffer,Typedef,我有一个类,它包含一个浮点型缓冲区,指向一个RGB值数组。缓冲区是正确创建和存储的,但是当我通过函数将该类的实例返回到main()时,缓冲区的内存是不可读的。这是初级课程: namespace imaging { typedef float component_t; class Image { protected: component_t * buffer; unsigned int width, heig
namespace imaging
{
typedef float component_t;
class Image
{
protected:
component_t * buffer;
unsigned int width, height;
public:
Image(unsigned int width, unsigned int height, const component_t * data_ptr) {
this->width = width;
this->height = height;
this->setData(data_ptr);
this->buffer = const_cast<component_t *>(data_ptr);
}
component_t getRedValPixel(unsigned int x, unsigned int y) const {
int pos = x * this->width * 3;
component_t red;
red = this->buffer[pos];
return r;
}
}
}
以下是main()函数中的代码:
Image* image = readIamge(filepath);
int width = image->getWidth(); //retrieves it correctly
int height = image->getHeight(); //retrieves it correctly
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
cout << image->getRedValPixel(i,j);
}
}
Image*Image=readIamge(文件路径);
int width=image->getWidth()//正确检索它
int height=image->getHeight()//正确检索它
对于(int i=0;i
让我们仔细看看您的返回语句:
return &Image(width, height, buffer);
return &Image(width, height, buffer);
执行Image(…)
操作时,会创建一个临时对象。一旦该临时对象所在的表达式结束,它将被销毁。然后返回指向该临时对象的指针,该对象将立即消失,并留下指向不存在对象的指针。尝试取消引用此指针将导致未定义的行为
从文件中读取的数据可能仍在内存中的某个位置,但无法从返回的指针中获取
我建议您改为按值返回对象,并研究移动语义、移动构造函数和。我还建议您不仅复制指向对象实际数据的指针,而且复制实际数据本身(深度副本)。返回和图像(宽度、高度、缓冲区);将返回堆栈中本地创建的对象的地址,该地址将在失去作用域后立即销毁(即返回语句)
解决方案是在堆中分配映像对象。
例如
main()
{
....
Image*Image=NULL;
readImage(文件路径、图像);
int width=image->getWidth();//正确检索它
int height=image->getHeight();//正确检索它
对于(int i=0;i
或
main()
{
....
Image*Image=NULL;
image=readImage(文件路径);
int width=image->getWidth();//正确检索它
int height=image->getHeight();//正确检索它
对于(int i=0;i
返回和图像(宽度、高度、缓冲区)代码>几乎肯定是错误的。您将返回指向临时对象的指针,该临时对象将在函数结束前被销毁。请(重新)阅读指针上的任何内容。@Yexo我明白了。谢谢你suggestion@i_ll_be_back我建议您不要返回指针,而是按值返回。在现代C++中,很少有需要使用指针的日子。如果您确实需要指针(主要用于多态性),那么请使用@i_______回来为什么要这样做?@SimonKraemer我必须遵循一个接口,此方法应返回指向此对象的指针。如果我重载&operator将缓冲区的临时数据传递给返回的对象,然后删除临时数据,该怎么办one@i_ll_be_back然后使用new
创建一个新对象,并返回new
提供给您的指针。@i\u将\u返回界面看起来不正确。如果确实需要返回指针,请使用返回新图像(宽度、高度、缓冲区)代码>。但是请记住,您现在必须自己管理对象的生命周期。因此,您需要在使用返回的指针后调用delete
,或者将其传递给智能指针(例如std::unique_ptr
),该指针将为您删除数据。
main()
{
....
Image* image = NULL;
readImage(filepath, image );
int width = image->getWidth(); //retrieves it correctly
int height = image->getHeight(); //retrieves it correctly
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
cout << image->getRedValPixel(i,j);
}
}
delete image;
image = NULL
...
}
void readImage(char* filepath, Image* o_pBuffer )
{
.....
o_pBuffer = new Image(width, height, buffer);
return o_pBuffer;
}
main()
{
....
Image* image = NULL;
image = readImage(filepath );
int width = image->getWidth(); //retrieves it correctly
int height = image->getHeight(); //retrieves it correctly
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
cout << image->getRedValPixel(i,j);
}
}
delete image;
image = NULL
...
}
Image* readImage(char* filepath )
{
.....
Image* o_pBuffer = new Image(width, height, buffer);
return o_pBuffer;
}