访问用new声明的数据的正确方式

The correct way of accessing data declared with new

本文关键字:方式 数据 访问 new 声明      更新时间:2023-10-16

我有这个伪代码。此代码可能不是100%正确。我的问题是,当您使用堆声明对象时?这是访问以下数据的正确方式。也就是说,如果你在堆上声明了一些东西,那么InfoMap也应该在堆上被声明吗?我知道两者都能工作,这是否意味着编译器会找到处理这一问题的最佳方法?

class InfoMap
{
    InfoMap(){}     
    QString name;
    int age;
}
class InfoData
{
  InfoMap RetrieveInfoList()
  {
    InfoMap map;
    map.name = "name1";
    map.age = 21;
    return map;
  }   
  InfoMap* RetrieveInfoList2()
  { 
    InfoMap *map = new InfoMap();
    map->name = "name1";
    map->age = 21;
    return map;
  }
}

在使用InfoData 的类中

void SomeClass::RetrieveData1()
{
    InfoData *data = new InfoData();
    InfoMap *map = data->RetrieveInfoList();
    qDebug() << map->name << map->age;
}
void SomeClass::RetrieveData2()
{
    InfoData *data = new InfoData();
    InfoMap map = data->RetrieveInfoList2();
    qDebug << map.name << map.age;
}

不,你不必这么做。但是,为了防止内存泄漏,必须最终对使用new分配的所有内容调用delete。在堆栈上创建对象的区别:

InfoData data;

和堆:

InfoData *data = new InfoData();

是对象的生存期。堆栈上的对象一旦超出范围就会被销毁。只要没有delete调用,堆上的对象就不会被销毁。因此,如果你忘记了这样做,你就会泄露内存。

至于您的代码,没有理由使用指针/new,您应该只使用堆栈存储:

class InfoMap
{
 public:
    InfoMap()
    {
    }
    QString name;
    int age;
};
class InfoData
{
 public:
  InfoMap RetrieveInfoList()
  {
    InfoMap map;
    map.name = "name1";
    map.age = 21;
    return map;
  }
};
In a class that uses InfoData
void SomeClass::RetrieveData()
{
    InfoData data;
    InfoMap map = data.RetrieveInfoList();
    qDebug() << map.name << map.age;
}

通过这种方式,编译器可以为您完成对象销毁。

如果您确实觉得有必要进行动态分配,那么您应该始终更喜欢智能指针而不是原始new/delete

我的问题是,当您使用堆声明一个对象时。

通常当您需要向(新创建的)对象传递或返回指针时。或者,如果它们太大而无法放在堆栈上。

在所有其他情况下,都可以避免在堆上分配对象。这也消除了对delete的需要,并避免了内存泄漏。

这是否意味着编译器将找到处理的最佳方法这

在这种情况下,编译器将执行您要求它执行的操作。

这两种解决方案都很好,都会起作用。它们之间的区别是:

1) 在第一种情况下(当您在堆栈RetrieveInfoList函数上分配一个InfoMap对象,然后返回它时),在return语句中,将调用InfoMap对象的复制构造函数。原始对象的副本将返回

2) 在第二种情况下,一个InfoMap对象被放置在堆上,并返回一个指针。

所以主要的区别是,在第一种情况下,你得到了对象的副本,而在第二种情况下你得到了原始对象。在您的情况下,考虑到InfoMap的结构,这只是性能问题(在第一种情况下是执行附加副本)。但是,如果InfoData包含一个默认副本构造函数无法正确处理的资源,那么代码的行为将与这两种情况不同。

OP,这里没有明显的理由让您使用new和delete;您可以(也应该)使用堆栈,而不是堆来做您正在做的事情。堆栈将通过自动销毁您在其作用域结束时创建的内容来取消分配您正在使用的内存,而使用"new"则会使内存不会自动取消分配,并且需要通过"delete"释放(我看不到您在使用它。您应该真的查找"内存泄漏")。所以不,不要在堆上声明InfoMap。