我正在阅读一些内容,并偶然发现:
当变量超出范围时调用析构函数
所以我的问题是没有析构函数的变量会发生什么?
例如:
class A {
public:
A () { }
};
void foo () {
A a;
}
int main (void) {
foo();
}
在这种情况下,a()
是吗?在完成a
之后,为foo()
分配的内存是否被破坏?
比我有这个例子:
class A {
std::vector <int> aa;
public:
A () : aa(5) { }
};
void foo () {
A b;
}
int main (void) {
foo();
}
在这种情况下,是否b
完成后分配给foo()
的内存也会被破坏?
我还要澄清一下:
class A {
public:
A () { }
};
等同于
class A {
public:
A () { }
inline ~A() = default;
};
但是我的问题是,foo()
完成后是否会调用此内联销毁?
编辑:
何时添加inline
析构函数作为默认值?
答案 0 :(得分:2)
如果您不提供析构函数,则编译器将为您提供一个析构函数。该析构函数将调用任何成员变量和基类的析构函数。
在某些情况下,必须编写析构函数以避免泄漏。一种情况是,如果您持有指向new
分配的对象的裸露指针,并且您的对象是“拥有”该指针的最佳人选。在大多数情况下,使用new
分配某些内容时,您会认为自己是指针的所有者。
另一种情况是您获得了其他种类的资源并需要释放它。例如,如果您打开文件或套接字,则可能需要编写一个自定义析构函数以将其关闭。
尽管如此,我对所有此类资源所做的事情是,我创建了一个包装资源并具有关闭该资源的析构函数的类。这将问题本地化,因此对于大多数代码,我必须尽可能少地记住资源管理方面的内容。这是C ++中的一个常见习语,被称为 RAII ,意思是“资源获取是初始化”。
这也是为什么您应该更喜欢make_unique
和make_shared
或类似vector
之类的东西来为new
分配内存的原因。它们为您提供了包装内存资源的对象,这些对象的析构函数将自动为您释放该资源。
要更彻底地回答您对我的回答的评论中的问题...
一旦控制离开声明了它的块,就会调用局部变量的析构函数。例如:
void foo () {
A b;
{
A c;
} // Destructor for c is called here
} // Destructor for b is called here.
答案 1 :(得分:1)
来自the standard:
如果类没有用户声明的析构函数,则将析构函数隐式声明为默认的([dcl.fct.def])。隐式声明的析构函数是其类的
inline public
成员。
换句话说,
class A {
public:
A () { }
};
等同于
class A {
public:
A () { }
inline ~A() = default;
};
关于你的问题
但是我的问题是,
foo()
完成后是否会调用此内联销毁?
答案是肯定的。但是,即使对于用户定义的析构函数也是如此。