我试图了解在这个例子中对象创建和销毁会发生什么。
#include <iostream>
class Person {
public:
const int name;
Person() = delete;
Person(int& name) : name(name) {
std::cout << "Person " << name << " created" << std::endl;
}
Person(const int& name) : name(name) {
std::cout << "Person " << name << " created -- copy constructor" << std::endl;
};
~Person() {
std::cout << "Person " << name << " destroyed" << std::endl;
}
};
class Family {
public:
Person mom, dad;
Family() = delete;
Family(Person& m, Person& d) : mom(m), dad(d) {
std::cout << "Family created" << std::endl;
};
Family(const Person& m, const Person& d) : mom(m), dad(d) {
std::cout << "Family created -- copy constructor" << std::endl;
};
~Family() {
std::cout << "Family destroyed" << std::endl;
}
};
int main()
{
Person* m = new Person(1);
Person* d = new Person(2);
Family f(*m, *d);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这输出
Person 1 created -- copy constructor
Person 2 created -- copy constructor
Family created
Family destroyed
Person 2 destroyed
Person 1 destroyed
Run Code Online (Sandbox Code Playgroud)
所以我不完全确定如何解释这一点。有人告诉我,我使用new
关键字堆分配的任何内容随后都应该是delete
-d。当对象移出作用域时,堆栈变量将丢失。我的理解是这样的。如果不是Person& m
通过引用接受,而是在没有&
, like 的情况下接受它Person m
,那么m
将被复制到这里(在堆栈上)并且我会发生内存泄漏,因为new Person("Jane")
永远不会删除堆分配的内容。
但既然我是引用它,我是否仍然有内存泄漏?双方m
并d
有自己的析构函数调用,但是这是否也是免费的堆内存?我怎么能想到Family.dad
?这是堆栈变量吗?如果是这样,那么整个是否Family
被认为是一个范围?
我对这个例子很困惑,真的不知道如何推理。另外,由于我从未明确显示delete
这两个Person
对象,因此我是否仍然存在内存泄漏?
添加复制构造函数以查看全图。
虽然Family::Family
通过引用获取对象,但它随后将它们复制到成员mom
和dad
. 因此,当这些成员被破坏时,您观察到的析构函数调用实际上会发生。
原始对象不会被释放 - 直到程序退出。
至于Person
您使用创建的实例的位置new
- 根据 C++ 标准,它们在“免费存储”中分配。通常,这意味着它们驻留在堆上。
OTOH,Family
实例(及其所有成员)具有“自动存储”。对于大多数流行的编译器/平台,这意味着它是在堆栈上分配的。