c++ - 在 C++ 中返回对象

标签 c++ memory-management factory

从类返回对象时,什么时候释放内存合适?

例子,

class AnimalLister 
{
  public:
  Animal* getNewAnimal() 
  {
    Animal* animal1 = new Animal();
    return animal1;
  }
}

如果我创建一个 Animal Lister 实例并从中获取 Animal 引用,那么我应该在哪里删除它?

int main() {
  AnimalLister al;
  Animal *a1, *a2;
  a1 = al.getNewAnimal();
  a2 = al.getNewAnimal();
}

这里的问题是 AnimalLister 没有办法跟踪创建的动物列表,所以我如何更改此类代码的逻辑以删除创建的对象。

最佳答案

根据您的使用情况,您可以在此处使用几个选项:

  1. 每次创建动物时都复制一份:

    class AnimalLister 
    {
    public:
      Animal getNewAnimal() 
      {
        return Animal();
      }
    };
    
    int main() {
      AnimalLister al;
      Animal a1 = al.getNewAnimal();
      Animal a2 = al.getNewAnimal();
    }
    

    优点:

    • 简单易懂。
    • 不需要额外的库或支持代码。

    缺点:

    • 需要Animal拥有一个表现良好的复制构造函数。
    • 如果 Animal 可能涉及大量复制庞大而复杂,尽管 return value optimization在许多情况下可以缓解这种情况。
    • 如果您计划返回派生自 Animal 的子类,则此方法无效因为他们将是sliced平淡无奇Animal ,丢失子类中的所有额外数据。
  2. 返回 shared_ptr<Animal> :

    class AnimalLister 
    {
    public:
      shared_ptr<Animal> getNewAnimal() 
      {
        return new Animal();
      }
    };
    
    int main() {
      AnimalLister al;
      shared_ptr<Animal> a1 = al.getNewAnimal();
      shared_ptr<Animal> a2 = al.getNewAnimal();
    }
    

    优点:

    • 适用于对象层次结构(无对象切片)。
    • 无需复制大型对象。
    • 无需Animal定义一个复制构造函数。

    缺点:

    • 需要 Boost 或 TR1 库,或其他智能指针实现。
  3. 跟踪所有 Animal AnimalLister 中的分配

    class AnimalLister 
    {
      vector<Animal *> Animals;
    
    public:
      Animal *getNewAnimal() 
      {
        Animals.push_back(NULL);
        Animals.back() = new Animal();
        return Animals.back();
      }
    
      ~AnimalLister()
      {
         for(vector<Animal *>::iterator iAnimal = Animals.begin(); iAnimal != Animals.end(); ++iAnimal)
            delete *iAnimal;
      }
    };
    
    int main() {
      AnimalLister al;
      Animal *a1 = al.getNewAnimal();
      Animal *a2 = al.getNewAnimal();
    } // All the animals get deleted when al goes out of scope.
    

    优点:

    • 非常适合需要大量 Animal 的情况s 在有限的时间内,并计划一次释放它们。
    • 轻松适应自定义内存池并释放所有 Animal s 在一个 delete .
    • 适用于对象层次结构(无对象切片)。
    • 无需复制大型对象。
    • 无需Animal定义一个复制构造函数。
    • 无需外部库。

    缺点:

    • 上面写的实现不是线程安全的
    • 需要额外的支持代码
    • 不如前两种方案清晰
    • 不明显的是,当 AnimalLister 超出范围时,它会带走 Animals。与 AnimalLister 相比,您不能再继续使用 Animals。

关于c++ - 在 C++ 中返回对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/204396/

相关文章:

c# - 如何防止类从外部实例化但保持可用?

c++ - 作为函数参数的字符串对的 C++ vector 的默认规范在 gcc-4.1.2 上无效?

linux - 什么是统一寻址内存?

c++ - std::set 为数组中的每个元素

java - 如何将字符串转换为一段代码(工厂方法模式?)

c++ - 这个函数应该返回什么类型的对象?

c++ - 将浮点 ostream 打印限制为一定长度?

c++ - 如何使用 CImg 显示少量图像(每个图像在单独的窗口中)?

c++ - 我在这里正确使用删除吗?

c++ - 从返回值 : how does it work? 创建 const 左值引用