我可以从前面提到的实例变量中为初始化列表中的数组获取堆内存吗?
Posted
技术标签:
【中文标题】我可以从前面提到的实例变量中为初始化列表中的数组获取堆内存吗?【英文标题】:Can I get memory on a heap for an array in an initialization list from prior mentioned instance variables? 【发布时间】:2020-04-01 01:13:16 【问题描述】:我正在尝试在自定义构造函数中创建对象时在堆上为数组分配内存。数组的大小由先前初始化的实例变量决定。为了清楚起见,这是我的代码。
struct PNG
PNG() = delete;
PNG(unsigned width, unsigned height):
d_width(width),
d_height(height),
d_imageData(new unsigned int [d_width * d_height])
;
PNG(PNG const &);
PNG & operator = (PNG & other);
friend std::ostream & operator << (std::ostream & os, PNG & png);
unsigned d_width;
unsigned d_height;
unsigned d_imageData; // unsigned d_imageData []; has the same issue
;
这段代码给了我错误:
error: cannot initialize a member subobject of type 'unsigned int' with an rvalue of
type 'unsigned int *'
d_imageData(new unsigned int [d_width * d_height])
我对两件事感到困惑:
-
在我看来,数组会请求内存,所以会
是一个容器,因此是
lvalue
而不是 rvalue
不会
有存储。
变量d_width
、d_height
在初始化列表中单独提及后是否可以访问?
我已经看到它这样做了,但想尝试初始化列表。现在,我正在通过玩代码来学习一些新东西。这是唯一可行的方法吗?
PNG(unsigned int width, unsigned int height)
width_ = width;
height_ = height;
imageData_ = new HSLAPixel[width * height];
This question 接近但它使用std::initializer_list
,我没有尝试使用它,并且我不需要接受答案中建议的模板。更重要的是,数组值将在稍后而不是在对象构造时填写。
【问题讨论】:
【参考方案1】:你的构造函数很好。但是由于您使用new[]
为d_imageData
分配内存,因此您需要将d_imageData
声明为指针类型,而不是整数类型,例如:
unsigned int *d_imageData; // <-- notice the *
(不要忘记包含一个调用 delete[] d_imageData;
的析构函数 - 请参阅 Rule of 3/5/0)。
是的,您可以在构造函数的成员初始值设定项列表中对new[]
的调用中使用d_width
和d_height
,因为它们在d_imageData
的声明中的PNG
之前声明,因此是在d_imageData
之前初始化。
【讨论】:
您可能还希望提及使用std::vector
或其他标准容器等选项,因为它们可以简化动态分配数组的管理
谢谢。那是我的愚蠢。为什么编译器会提到rvalue
?是指类型,unsigned int
还是[d_width * d_height]
?
@heretoinfinity - 提到的右值是new
表达式的结果。编译器可能以一种过于复杂但技术上正确的方式告诉您,new
表达式(指针unsigned int *
)的结果不能存储在unsigned int
中。
@Peter,谢谢。我应该提到现有的实现使用数组。我只是在玩代码,试图了解如何自行组合operator=
以确保我理解它,并从这个摆弄来理解初始化列表开始。如果我自己从头开始设计,我会选择std::vector
。以上是关于我可以从前面提到的实例变量中为初始化列表中的数组获取堆内存吗?的主要内容,如果未能解决你的问题,请参考以下文章