假设在C ++中,我有以下代码:
class Foo {
private:
double* myData;
public:
Foo(double data[]) {
myData = data;
}
}
int main() {
double mainData[] = {1.0};
Foo myfoo(mainData);
}
据我所知,mainData
在传递给Foo
构造函数时被视为指针,因此行myData = data
仅指定指针地址。所以这里没有分配额外的内存,对吗?但是,Foo
类是否负责提供释放myData
内存的析构函数?或者我们是否有一个实际指向堆栈内存的动态数组指针?
此外,如果我想保护Foo
myData
在更改mainData
时更改,是否有一种强制Foo
构造函数的简单方法要复制吗?理想情况下,myData
将是一个简单的数组,而不是指针,但将行double* myData
更改为double myData[]
似乎无法正常工作,因为在运行时,数组的大小是未知的。
答案 0 :(得分:3)
此处的参数不是动态数组:
Foo(double data[])
事实上,声明等同于:
Foo(double * data)
即使decltype
也会告诉你它们是同一个东西,这两个签名会因重载而发生冲突。
所以,没有分配。您只是将指针传递给数组的第一个元素。
此外,C ++将自动复制数组的唯一位置是它是类的成员,并且成员不允许使用不确定大小的空括号[]
语法。 (或者,如果是,则在生成复制构造函数或赋值运算符之前,已经通过类类型完成的时间确定了大小。)
另外,如果我想在更改mainData时保护Foo的myData不被更改,是否有一种简单的方法可以强制Foo构造函数复制它?理想情况下,myData将是一个简单的数组,而不是一个指针,但是将double * myData行更改为double myData []并不会起作用,因为在运行时,数组的大小是未知的。
您可以保留数据的副本,但如果在编译时其大小(或至少是上限)未知,则需要指针。我建议std::vector
使用裸指针,或至少std::unique_ptr< double[] >
。
答案 1 :(得分:2)
在这种情况下,myData指向堆栈上的一个地址,当函数超出范围时,它会调用Foo的析构函数。通常,当您使用关键字new来分配它们时,数组被描述为动态的。
至于你的第二个问题,你可能不得不向构造函数传递一个指向数组和数组长度的指针。然后,您需要使用传入的长度动态创建一个double数组(由myData指向),然后进行复制。
不要忘记删除析构函数中的内存。
答案 2 :(得分:1)
new
或delete
涉及指针与分配或解除分配无关。因此,您的代码不会调用任何内存分配。delete[] foo;
答案 3 :(得分:0)
是的,它没有分配额外的内存。
不,如果没有被告知,析构函数将不会对类字段做任何事情。
答案 4 :(得分:0)
将具有指向由其他类分配/管理的数据的指针,这是非常糟糕的设计。最好的办法是让Foo构造函数复制并将其存储在指针中。然后在析构函数中释放那一个。这需要将数组的长度传递给Foo构造函数。我希望有所帮助。