Karlovsky120 Karlovsky120 - 1 month ago 9
C++ Question

Failing to return a unique_ptr

HPP:

class Camera {
public:
Camera(float FOV, float nearPlane, float farPlane);

std::unique_ptr<glm::mat4x4> getProjectionMatrix();

private:
std::unique_ptr<glm::mat4x4> projectionMatrix;
};


CPP:

Camera::Camera(float FOV, float nearPlane, float farPlane) {

float aspectRatio = DisplayManager::displayWidth / DisplayManager::displayHeight;

projectionMatrix = std::make_unique<glm::mat4x4>();
*projectionMatrix = glm::perspective(FOV, aspectRatio, nearPlane, farPlane);
}

std::unique_ptr<glm::mat4x4> Camera::getProjectionMatrix() {
//std::unique_ptr<glm::mat4x4> projectionMatrix = std::make_unique<glm::mat4x4>();
//*projectionMatrix = glm::perspective(90.0f, 1.333f, 0.1f, 1000.0f);
return std::move(projectionMatrix);
}


Look at the two commented lines. The program will compile whether they are commented out or not, but if they are, the data will be corrupted.

How can I write a getter that returns a unique_ptr that is a private member of the class? How do I set the unique_ptr properly in the constructor?

Answer

Here's a much better idea: stop needlessly allocating memory. Have Camera store a glm::mat4x4 directly, not as a unique_ptr. C++ is not Java; you don't have to allocate everything with new. All your code becomes much simpler:

Camera::Camera(float FOV, float nearPlane, float farPlane)
    : projectionMatrix(glm::perspective(FOV, (DisplayManager::displayWidth / DisplayManager::displayHeight), nearPlane, farPlane))
{
}

glm::mat4x4 &Camera::getProjectionMatrix() { return projectionMatrix; }

However, if you absolutely have to use a unique_ptr in Camera, then you should return a reference, not a smart pointer:

glm::mat4x4 &Camera::getProjectionMatrix() { return *projectionMatrix; }