减少C++中的内存消耗

问题描述 投票:0回答:1

我正在用 C++ 编写一个头文件,实现与四元数的交互。四元数可以解释为

a + bi + cj + dk
,因此它的组成部分以
m_value
顺序存储在
b, c, d, a
中。我还支持将四元数表示为标量和向量。我注意到,在方法
updateComponents() 
中,我使用的内存比实际需要的内存多 2 倍。我该如何解决这个问题?
m_value
以及标量和向量表示是必需的。

#ifndef QUAT_HPP
#define QUAT_HPP

#include <cmath>

template<typename T>
struct matrix_t {
    T data[16];
};

template<typename T>
struct vector3_t {
    T x, y, z;
};

template<typename T>
class Quat {
public:
    Quat() : scalar(0), vector{0, 0, 0} {
        updateComponents();
    }

    Quat(T a, T b, T c, T d) : scalar(a), vector{b, c, d} {
        updateComponents();
    }

    Quat(T angle, bool mode, vector3_t<T> axes) {
        if (!mode) {
            angle = angle * M_PI / 180;
        }
        T norm = std::sqrt(axes.x * axes.x + axes.y * axes.y + axes.z * axes.z);
        scalar = std::cos(angle / 2);
        vector.x = axes.x / norm * std::sin(angle / 2);
        vector.y = axes.y / norm * std::sin(angle / 2);
        vector.z = axes.z / norm * std::sin(angle / 2);
        updateComponents();
    }

    const T *data() const { return m_value; };

    Quat<T> operator+(const Quat<T> &q2) const {
        return Quat(scalar + q2.scalar, vector.x + q2.vector.x, vector.y + q2.vector.y, vector.z + q2.vector.z);
    }

    Quat<T> &operator+=(const Quat<T> &q2) {
        *this = *this + q2;
        updateComponents();
        return *this;
    }

    Quat<T> operator-(Quat q2) const {
        return Quat(scalar - q2.scalar, vector.x - q2.vector.x, vector.y - q2.vector.y, vector.z - q2.vector.z);
    }

    Quat<T> &operator-=(Quat q2) {
        *this = *this - q2;
        updateComponents();
        return *this;
    }

    Quat<T> operator*(Quat q2) const {
        T a1 = scalar, b1 = vector.x, c1 = vector.y, d1 = vector.z;
        T a2 = q2.scalar, b2 = q2.vector.x, c2 = q2.vector.y, d2 = q2.vector.z;
        return Quat(
                a1 * a2 - b1 * b2 - c1 * c2 - d1 * d2,
                a1 * b2 + a2 * b1 + c1 * d2 - c2 * d1,
                a1 * c2 + a2 * c1 + d1 * b2 - d2 * b1,
                a1 * d2 + a2 * d1 + b1 * c2 - b2 * c1);
    }

    Quat<T> operator*(T s) const { return Quat(scalar * s, vector.x * s, vector.y * s, vector.z * s); }

    Quat<T> operator*(vector3_t<T> vec) const {
        Quat<T> q2 = Quat(0, vec.x, vec.y, vec.z);
        return *this * q2;
    }

    Quat<T> operator~() const { return Quat(scalar, -vector.x, -vector.y, -vector.z); }

    bool operator==(Quat q2) const {
        return (scalar == q2.scalar && vector.x == q2.vector.x && vector.y == q2.vector.y && vector.z == q2.vector.z);
    }

    bool operator!=(Quat q2) const { return !(*this == q2); }

    explicit operator T() const {
        return std::sqrt(scalar * scalar + vector.x * vector.x + vector.y * vector.y + vector.z * vector.z);
    }

    matrix_t<T> rotation_matrix() const {
        Quat<T> q = normalize();
        T s = q.scalar, x = q.vector.x, y = q.vector.y, z = q.vector.z;
        T r_11 = 1 - 2 * y * y - 2 * z * z, r_12 = 2 * x * y - 2 * z * s, r_13 = 2 * x * z + 2 * y * s,
          r_21 = 2 * x * y + 2 * z * s, r_22 = 1 - 2 * x * x - 2 * z * z, r_23 = 2 * y * z - 2 * x * s,
          r_31 = 2 * x * z - 2 * y * s, r_32 = 2 * y * z + 2 * x * s, r_33 = 1 - 2 * x * x - 2 * y * y;
        return {r_11, r_21, r_31, 0, r_12, r_22, r_32, 0, r_13, r_23, r_33, 0, 0, 0, 0, 1};
    }

    matrix_t<T> matrix() const {
        return {scalar, -vector.x, -vector.y, -vector.z, vector.x, scalar, -vector.z, vector.y,
                vector.y, vector.z, scalar, -vector.x, vector.z, -vector.y, vector.x, scalar};
    }

    T angle(bool mode = true) const { return mode ? 2 * std::acos(scalar) : 2 * std::acos(scalar) * 180 / M_PI; }

    vector3_t<T> apply(vector3_t<T> vec) const {
        Quat<T> q = normalize();
        Quat<T> qv = q * vec;
        Quat<T> qq = qv * (~q);
        return {qq.vector.x, qq.vector.y, qq.vector.z};
    }

private:
    T m_value[4];
    T scalar;
    vector3_t<T> vector;

    void updateComponents() {
        m_value[3] = scalar;
        m_value[0] = vector.x;
        m_value[1] = vector.y;
        m_value[2] = vector.z;
    }

    Quat<T> normalize() const {
        T norm = T(*this);
        return *this * (1 / norm);
    }
};
#endif

我读过有关

union
的内容,但我认为它不会像我预期的那样节省内存。

c++ optimization
1个回答
0
投票

如果您需要 *data() 返回它是什么,您有 2 个选择。对所有内容都使用 m_value,使用 [0] 而不是 .x 等看起来不太好,但它会做你想做的事。
或者,您可以通过在每次 *data() 调用中新建和分配一个本来是 m_value 的数组来陷入手动内存管理的困境。如果您不小心使用它,这将有可能很快使用比您现在拥有的更多的内存,但它确实具有不让其他代码像现在一样干扰您的私有成员的优点

© www.soinside.com 2019 - 2024. All rights reserved.