我研究@Configuration
public class MailConfig {
@Bean
@ConditionalOnProperty(name="spring.mail.host",
havingValue="foo",
matchIfMissing=true)
public MailSender mockMailSender() {
return new MockMailSender();
}
@Bean
@ConditionalOnProperty(name="spring.mail.host")
public MailSender smtpMailSender(**JavaMailSender javaMailSender**) {
SmtpMailSender mailSender = new SmtpMailSender();
mailSender.setJavaMailSender(javaMailSender);
return mailSender;
}
}
概念。我在构造函数和Destractor概念中感到困惑。编译器在退出程序时将隐式调用析构函数。但在我的程序中,只有构造函数调用。
C++
输出:
#include <iostream>
using namespace std;
class A
{
int i;
public:
A()
{
cout<<"Constructor call"<<endl;
}
~A()
{
cout<<"Destructtor call"<<endl;
}
};
int main()
{
A *a = new A();
}
所以,我有疑问:为什么析构函数在退出程序时不会被编译器隐式调用?
答案 0 :(得分:7)
为什么析构函数在退出程序时不会被编译器隐式调用?
因为动态分配的对象不会自动销毁。这就是指定语言的方式。跟踪动态对象的破坏需要运行时/内存开销。
解决方案:不要泄漏动态分配的对象。
答案 1 :(得分:4)
C ++中有两种“变量生命周期”类型。动态和自动。
自动就像:
$request->request->get("data-name");
此处,void foo()
{
int i; // automatic storage
} // destroys i
将在离开范围时被破坏(i
返回后)。您可以通过使对象具有自动生命周期来自行检查:
foo
你会看到构造函数和析构函数都会被调用。
第二种形式是动态分配的内存。您可以使用int main()
{
A a; // calls A's constructor and allocates memory.
} //calls A's destructor and frees the memory used.
(与您一样)动态分配内存,并使用new
释放内存。编译器不会为您执行此操作。
这意味着,要破坏对象,您必须自己明确调用delete
:
delete
如果你没有打电话给int main()
{
A* a = new A();
delete a; // calls A's destructor and frees the memory used.
}
(就像你的代码一样),那么当程序离开delete
时,指针main
就会被销毁,现在我们有一块内存,无法达到因此,没有人可以清理(a
),这意味着你是leaking memory。
但是,现代操作系统会在程序结束时自动回收程序使用的所有内存,因此此时无关紧要。这意味着您的析构函数不会像您刚刚目睹的那样被调用。
动态分配的内存允许你做一些漂亮的技巧,比如控制对象的生命周期到你想用delete
自己明确销毁它们的点。使用delete
和new
的问题在于忘记单个delete
很容易,并且您的程序已经泄漏内存,这就是为什么建议远离这种分配方式
如果由于某种原因你绝对需要动态生命周期,那么使用像delete
这样的智能指针,它会在它超出范围时为你调用std::unique_ptr
和new
。
答案 2 :(得分:3)
使用import java.util.ArrayList;
import java.util.Map;
import com.my.ContextDroolsObject;
dialect 'java'
rule 'Soccer Image Theme'
salience 100
when
s : ContextDroolsObject()
objectsm : Map() from s.objects
imageThemesList : ArrayList() from outputsm.imageThemes
then
System.out.println("-----------------------soccer");
end
动态创建对象。仅当使用new
删除对象时才会调用析构函数。
为了防止内存泄漏,您可以/应该使用delete
等智能指针。
在任何情况下,当进程结束时,内存本身当然会被释放。
答案 3 :(得分:2)
从不在代码中调用析构函数,因为对象永远不会被销毁。
您动态分配A
对象,并且永远不会释放它。将delete a;
添加到main()
,您将看到正在运行的析构函数:
int main()
{
A *a = new A();
delete a;
return 0;
}
答案 4 :(得分:1)
在main函数中,您创建一个指针变量,您必须在主函数结束时通过delete a
将其删除。
答案 5 :(得分:0)
因为你有内存泄漏。您动态创建了一个new
的对象,承诺您将管理对象的生命周期并稍后使用delete
进行清理。然后你违背了这个承诺。
如果您以通常的方式创建对象:
A a;
然后它将自动销毁。