基本上,如果我创建一个新类的多个实例,我是否需要为每个实例调用析构函数,或者在销毁每个实例时调用它(如果我使用模糊/错误的术语,构造函数,我道歉/析构函数是我还没有完全掌握的概念。
更具体地说,这是我正在使用的一些代码(如果风格不好,我必须再次道歉,我对学校问题有了一个想法,并希望得到代码快)。
while(read >> f >> l >> t >> s >> sta >> acct >> bal)
{
cout << "test" << endl;
ptr[i] = new account(f,l,t,s,sta,acct,bal);
ptr[i]->printcontents();
cout << "test" << endl;
i++;
cout << i << endl;
}
因此,为了这个问题,假设这个循环三次。我是否只需要调用&#34; account&#34;的析构函数曾经摧毁所有三个新账户的情况,还是一个电话会离开另外两个?这甚至是一个好习惯吗?
编辑:我注意到我的一些帖子被截断了,所以我添加了最后几行,但人们已经解决了这个问题。我用户指针的原因纯粹是因为作业决定我这样做;坦率地说,我现在没有看到使用它们的重点,但我认为它们在某个地方变得有用。我还应该补充说,动态内存分配也应该在赋值中使用。
答案 0 :(得分:5)
自动调用析构函数,您通常不必担心,除非您使用new
动态分配内存。
在这种情况下,一旦您不再需要,就必须为每个已分配的内存拨打delete
。
请注意,如果您使用new []
分配数组,则必须使用delete[]
进行解除分配:
int *a = new int[10]; // allocating an array of 10 integers
//...
delete[] a; // release memory
在现代C ++中,您应该考虑可以为您完成工作的托管指针。类似的东西:
while(read >> f >> l >> t >> s >> sta >> acct >> bal)
{
cout << "test" << endl;
ptr[i] = std::make_unique<account>(f,l,t,s,sta,acct,bal);
ptr[i]->printcontents();
cout << "test" << endl;
i++;
cout << i << endl;
}
在这里,std::make_unique
将返回std::unique_ptr
,在销毁时会在相关内存上调用delete。
最后一点:你确定你真的需要指针吗?很难说你的例子,但根据你的用法,你也可以创建静态分配的对象:
while(read >> f >> l >> t >> s >> sta >> acct >> bal)
{
cout << "test" << endl;
ptr[i] = account(f,l,t,s,sta,acct,bal);
ptr[i].printcontents();
cout << "test" << endl;
i++;
cout << i << endl;
}
答案 1 :(得分:3)
每个new
应该与delete
如果你有一个指针数组,并且每个指针都有new
,那么你需要delete
每个实例。
如果另一方面你new
一个对象数组,那么你可以delete []
整个数组。
作为一个侧面点,对于您的代码,而不是使用ptr
(您没有告诉我们详细信息,请考虑使用std::vector<account>
并使用push_back
然后将根据需要自动调整大小,而不是ptr[i] = new...
。
答案 2 :(得分:1)
通常,您必须删除您创建的每个实例。具体如何做到这一点取决于......但简单的经验法则是:
对于let youtubeURL = "https://www.youtube.com/watch?v=uH8o-JTHJdM"
let regex = try! NSRegularExpression(pattern: "\\?.*v=([^&]+)", options: .caseInsensitive)
let match = regex.firstMatch(in: youtubeURL, options: [], range: NSRange(location: 0, length: youtubeURL.characters.count))
if let videoIDRange = match?.rangeAt(1) {
let substringForFirstMatch = (youtubeURL as NSString).substring(with: videoIDRange)
} else {
//NO video URL
}
的每次使用,必须使用new
。
对于delete
的每次使用,必须使用new[]
。
如果从自动声明中获取实例,则不必执行任何操作,因为它将使用其堆栈框架进行销毁;但如果你创造了它,就会将其销毁。
答案 3 :(得分:1)
正如其他人所说,如果你使用new
,那么就需要delete
。但是,你真正的麻烦是概念性的。您问一个好问题,new
和delete
是外围的。
超过99.5%的时间正常使用析构函数是让编译器自动调用它们。 (0.5%的例外是深奥的。我们现在不需要担心。)
考虑以下代码片段:
int n = 5;
{
int m = 2;
++m;
n *= m;
// The variable m is automatically destructed here.
}
// Here, n == 15.
看看它是如何工作的?当m
到达生命的终点时,会自动调用m
的析构函数,因为m
不是由new
生成的)在块的末尾发生其中m
被实例化。
当然,m
是int
,因此它的析构函数不做任何事情(或者,如果您愿意,m
没有析构函数)。您自己定义的其他类型(如类型account
)可以包含析构函数。在单个对象(account
的实例)达到其生命周期时,析构函数将自动针对单个对象进行调用。
新增和删除
那么,这与new
和delete
有何关系?
在我的代码片段中,我没有使用new
。因此,我的对象的生命周期由封闭的括号控制。
在您的代码片段中,您确实使用了new
。因此,您使用delete
来控制对象的生命周期。
当然,您忘记使用delete
,这就是为什么您的对象永远不会被破坏(除非您的整个程序退出)。
其他人已经注意到,现代C ++提供了new
的改进替代方案,您应该在大多数情况下使用它。你可以阅读他们的答案。但是,从机械方面来说,理解new
做什么以及delete
如何配对它仍然非常有用。
手工调查导师
您几乎肯定不必担心这一点,因为手动调用析构函数的情况很少见且很先进。基本上,如果你自己管理一个存储对象的存储器(你几乎从不这样做,但很少有例外),那么编译器就无法分辨何时进行销毁,所以你必须在什么时候告诉它。有关典型的深奥示例,请参阅this。
答案 4 :(得分:0)
只有指针需要调用析构函数来删除它们或关闭程序