c++中的垃圾收集/析构函数
garbage collection/destructors in C++
我是c++新手。据我所知,与java不同,c++没有自动垃圾处理,所以我们在类中为对象添加析构函数:
class A{
class A();
~class A(); // destructor
};
我很好奇当我们使用结构体时会发生什么。另外,如果不向类添加析构函数,会发生什么情况?内存是如何释放的?
c++中结构体和类之间的唯一区别是默认的访问控制——默认情况下,类的成员是私有的,而结构体的成员是公有的。如果你不定义自己的析构函数,编译器会给你一个默认的析构函数;当对象被销毁时,所有成员也被销毁。只有当任何类成员指向堆分配的内存时,才需要定义自己的析构函数。
适用于类的相同规则也适用于c++中的结构体,唯一的例外是默认访问级别,而不是其他。
如果不定义析构函数,编译器将为您定义默认析构函数。可用于类和结构。
默认构造函数调用基类的析构函数和所有具有它们的成员的析构函数。默认析构函数只是一种商品,如果你不需要对你的类做任何特别的事情,你不需要手动编写一个空版本(比如从堆中释放一个动态分配的对象,或者管理非自动成员)。
c++没有任何垃圾收集。这几乎是真的。析构函数是一个非常有用的工具,也用于收集垃圾。
类中有4个预定义的方法:默认构造函数、复制构造函数、赋值操作符的重载和析构函数。这意味着这些方法有一个默认版本:
- 默认构造函数将调用所有类成员的默认构造函数。
- 复制构造函数将所有类成员复制到另一个。赋值操作符就像一个特殊的复制构造函数。
- 默认析构函数将调用所有类成员的析构函数。
当你定义:
class A {
private:
int* a;
public:
A() { a = new int(5); }
};
默认析构函数只会擦除指针在自身中分配的内存,而不会释放int(5)
占用的内存。
~A() { delete a; }
或者使用智能指针。
我认为比较Java和c++是一个很好的回答。在Java中,所有引用类型都存储在堆中,而所有原语都存储在堆栈中。这意味着,当原语超出作用域时,它们将被销毁;也就是说,当声明它们的方法返回时。另一方面,引用类型则不是这样。
在c++中,您可以控制哪个变量是动态存储(在堆中)还是自动存储(在堆栈中)。如果您使用new
操作符创建了一个对象,它将一直留在堆中,直到您使用相应的delete
释放该内存。如果您创建一个没有new
操作符的变量(或对象),当对象超出作用域时,它的内存将被释放。
回答你关于构造函数和析构函数的问题:构造函数是一种总是在创建新对象时调用的方法。如果不指定任何构造函数,则暗示使用默认构造函数(不带参数)。当对象超出作用域时,或者使用delete
操作符将其删除时(在使用new
动态创建它的情况下),将调用析构函数。
- 什么时候调用组成单元对象的析构函数
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 内联映射初始化的动态atexit析构函数崩溃
- 什么时候调用析构函数
- 优先顺序:智能指针和类析构函数
- C++-明确何时以及如何调用析构函数
- 使用基类指针创建对象时,缺少派生类析构函数
- 在c++中使用向量时,如何调用构造函数和析构函数
- 重载运算符new[]的行为取决于析构函数
- 我需要知道编译器如何在cpp中使用析构函数
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 析构函数调用
- 通过引用传递-为什么要调用这个析构函数
- 对具有动态分配的内存和析构函数的类对象的引用
- 重载 -> shared_ptr 个实例中的箭头运算符<interface>,接口中没有纯虚拟析构函数
- C++成员的析构函数顺序与shared_ptr
- C++ 防止在映射中放置()时调用析构函数
- 在这种情况下显式调用时,std::cout 如何更改析构函数的行为?
- 调用析构函数以释放动态分配的内存
- 不命名构造函数和析构函数上的类型错误