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

时间:2016-01-02 17:46:10

标签: c++

我有这个伪代码。此代码可能不是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;
}

4 个答案:

答案 0 :(得分:1)

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

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上的智能指针。

答案 1 :(得分:0)

  

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

通常需要传递或返回指向(新创建的)对象的指针。或者也许如果它们太大而无法叠加。

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

  

这是否意味着编译器将找出最佳处理方式   此?

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

答案 2 :(得分:0)

这两种解决方案都很好并且可行。他们之间的区别是:

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

2)在第二种情况下,一个InfoMap对象在堆上被淘汰,并且将返回它的一个poiter。

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

答案 3 :(得分:0)

OP,这里没有明显的理由让你使用new和delete;你可以(并且应该)使用堆栈,而不是堆,用于你正在做的事情。堆栈将通过自动销毁您在其范围的末尾创建的内容来取消分配您正在使用的内存,而使用&#34; new&#34;这使得内存不会自动解除分配,需要通过&#34; delete&#34; (我不会看到你使用。你应该真的查找&#34;内存泄漏&#34;)。 所以不,不要在堆上声明InfoMap。