通过引用传递取消引用的指针时了解 C++ 堆/堆栈分配

Pav*_*lin 1 c++ pointers

我试图了解在这个例子中对象创建和销毁会发生什么。

#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")永远不会删除堆分配的内容。

但既然我是引用它,我是否仍然有内存泄漏?双方md有自己的析构函数调用,但是这是否也是免费的堆内存?我怎么能想到Family.dad?这是堆栈变量吗?如果是这样,那么整个是否Family被认为是一个范围?

我对这个例子很困惑,真的不知道如何推理。另外,由于我从未明确显示delete这两个Person对象,因此我是否仍然存在内存泄漏?

Igo*_* R. 5

添加复制构造函数以查看全图。

虽然Family::Family通过引用获取对象,但它随后将它们复制到成员momdad. 因此,当这些成员被破坏时,您观察到的析构函数调用实际上会发生。

原始对象不会被释放 - 直到程序退出。

至于Person您使用创建的实例的位置new- 根据 C++ 标准,它们在“免费存储”中分配。通常,这意味着它们驻留在堆上。

OTOH,Family实例(及其所有成员)具有“自动存储”。对于大多数流行的编译器/平台,这意味着它是在堆栈上分配的。

  • @Pavlin 复制构造函数复制“它自己”类型的对象。所以它们应该是`Family(const Family&amp;)`和`Person(const Person&amp;)`。 (2认同)