动态分配对象生成器

Dynamically allocated object producer

本文关键字:对象 动态分配      更新时间:2023-10-16

看这个班:

//HPP
class A {
  public:
    A();
    ~A();
    B *fetchNew();
  private:
    B *currentValue;
}

//CPP
A::A() {}
A::~A {
   delete currentValue;
}
B *A::fetchNew() {
    delete currentValue;
    currentValue = new B();
    //apply magic to currentValue
    return currentValue;
}

这个类持有一个指向类b实例的指针。每次调用fetchNew()时,旧的被删除,一个新的被分配,并对它应用魔法,在新的和闪亮的currentValue返回之后。

这个方法被频繁调用(在现实生活中,它是一个在游戏主循环中返回视图矩阵的方法,所以它每帧被调用一次,大约每秒60次)。

一旦A对象被删除,它将删除当前的currentValue,否则会泄漏。

有更漂亮的方法来实现这一点吗?

编辑:

下面是实际代码,因为它有一个转折(只是fetchNow()方法):
glm::mat4x4 *Camera::getViewMatrix() {
    //transformation <<-apply shiny and fancy magic;
    delete viewMatrix;
    viewMatrix = new glm::mat4x4();
    *viewMatrix *= glm::mat4_cast(transformation->getRotation());
    *viewMatrix = glm::translate(*viewMatrix, transformation->getPosition());
    return viewMatrix;
}

有更漂亮的方法来实现这一点吗?

我建议使用 std::unique_ptr<B> 而不是原始指针B*:

//HPP
#include <memory>
class A {
  public:
    A();
    ~A();
    std::unique_pty<B> fetchNew();
  private:
    // You don't need that: B *currentValue;
}

//CPP
A::A() {}
A::~A {
   // You don't need that: delete currentValue;
}
std::unique_ptr<B> A::fetchNew() {
    // You don't need that: delete currentValue;
    std::unique_ptr<B> newValue = std::make_unique<B>();
    // apply magic to newValue and dereference using * or -> as with any raw pointer
    return newValue;
}

这种方法有几个优点:

  • 您不必关心A中的删除或内存泄漏
  • fetchNew()结果的所有权转移在语义上是清晰的
  • 这是一个更清晰的API,客户端将知道他们获得了指针的所有权,而不必考虑是否需要删除该实例
  • 您为客户端提供了自行确定B实例的生命周期范围的灵活性。

对于您编辑的添加,它应该看起来像:

std::unique_ptr<glm::mat4x4> Camera::getViewMatrix() {
    //transformation <<-apply shiny and fancy magic;
    std::unique_ptr<glm::mat4x4> viewMatrix = std::make_unique<glm::mat4x4>();
    *viewMatrix *= glm::mat4_cast(transformation->getRotation());
    *viewMatrix = glm::translate(*viewMatrix, transformation->getPosition());
    return viewMatrix;
}