gpt4 book ai didi

c++ - 删除动态内存如何真正起作用?

转载 作者:太空宇宙 更新时间:2023-11-03 10:37:30 25 4
gpt4 key购买 nike

在 main 中,我有两种类型的对象:Person 和 Pet。一个人可以拥有多只宠物。我正在动态创建这两种类型的对象。

#include <iostream>
#include <string>
#include <vector>

struct Pet
{
Pet() { }

Pet(std::string name, std::string type)
{
Name = name;
Type = type;
std::cout << Name << " is created" << std::endl;
}
~Pet()
{
std::cout << Name << " is destroyed" << std::endl;
}

std::string GetName() { return Name; }
std::string GetType() { return Type; }

std::string Name;
std::string Type;
};

struct Person
{
Person(std::string name)
{
Name = name;
std::cout << Name << " is created" << std::endl;
}

~Person()
{
std::cout << Name << " is destroyed" << std::endl;
}

void AddPet(Pet& pet)
{
Pets.push_back(pet);
}

std::string GetPersonsPets()
{
if (Pets.size() == 0)
{
return Name + " has no pets";
}
if (Pets.size() == 1)
{
return Name + " has " + Pets[0].GetName() + ",a " + Pets[0].GetType();
}
}

std::string Name;
std::vector<Pet> Pets;
};

int main()
{
Person* peter = new Person("Peter");

Person* alice = new Person("Alice");

Pet* fluffy = new Pet("Flyffy", "dog");
peter->AddPet(*fluffy);

std::vector<Person*> People;
People.push_back(peter);
People.push_back(alice);

int i = 0;
for (std::vector<Person*>::iterator it = People.begin(); it != People.end();
it++)
{
std::cout << People[i]->GetPersonsPets() << std::endl;
i++;
}
//delete fluffy;
delete alice;
delete peter;
}

一切似乎都正常,但在删除 Pet 对象时会发生一些有趣的事情。当我取消注释 delete fluffy 时,fluffy 会在 peter 之后自动删除。

我认为,由于 fluffy 是动态创建的,除非我自己这样做,否则它永远不会被销毁?

但是当我不取消注释 delete fluffy 时会发生另一件有趣的事情。然后它的析构函数将被调用两次。

一个东西怎么可能被破坏两次?

最佳答案

当你在这里添加宠物时:

peter->AddPet(*fluffy);

那么 *fluffy 就是指针的引用,这里

void Person::AddPet(Pet& pet)
{
Pets.push_back(pet);
}

您将 *fluffy 的拷贝存储在某个容器中(我想它是一个 std::vector)。

你看到被销毁的对象是那些拷贝(vector 管理它自己的内存,即当 vector 被销毁时它会销毁它的元素)。您仍然需要删除在 main 中创建的动态分配的实例。

请注意,您最好不要在这里使用 newdelete。必要时使用动态内存。当你这样做时,你最好使用智能指针而不是原始指针。

PS 您的代码展示了编写 getter 的不良做法,因为。 PetPerson 的所有成员都是公开的。使成员私有(private)或删除 getters。两者都有误导。此外,如果您确实提供了默认构造函数 (Pet(){}),它应该将成员初始化为有意义的值。构造函数的工作是构造一个处于有效状态的对象。最后但并非最不重要的一点是,您应该像在

中那样为构造函数使用成员初始化列表
Pet(std::string name, std::string type) : Name(name),Type(type) {}

关于c++ - 删除动态内存如何真正起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58666673/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com