Возвратите массив плавающий в C++

Я в настоящее время имею 4x4 матричный класс в C++, и я храню каждое значение как плавание:

Matrix4d::Matrix4d(const float& m00, const float& m01, const float& m02, const float& m03,
                   const float& m10, const float& m11, const float& m12, const float& m13,
                   const float& m20, const float& m21, const float& m22, const float& m23,
                   const float& m30, const float& m31, const float& m32, const float& m33)
{
    _m00 = m00;
    _m01 = m01;
    _m02 = m02;
    _m03 = m03;
    _m10 = m10;
    _m11 = m11;
    _m12 = m12;
    _m13 = m13;
    _m20 = m20;
    _m21 = m21;
    _m22 = m22;
    _m23 = m23;
    _m30 = m30;
    _m31 = m31;
    _m32 = m32;
    _m33 = m33;
}

Мой вопрос, как я могу возвратить массив плавающий этих данных? У меня нет проблемы при создании массива в классе, например:

float arrayToReturn[16] = { m00, m01, m02, m03, ... m33 };

Однако я не могу возвратить это значение от класса. Я читал о возврате указателя на массив, но не имел никакой удачи с ним.

5
задан ingh.am 21 April 2015 в 23:26
поделиться

4 ответа

Это сработает, если ваш внутренний массив будет выглядеть как float array[4][4]:

float** Matrix4d::getMatrix();

Если ваш внутренний массив будет одномерным:

float* Matrix4d::getMatrix();

Но оба случая открывают внутреннюю работу вашего класса внешнему миру, что делает ваш код менее безопасным и более трудным для сопровождения.

Лучше было бы создать конструктор копирования, оператор () и оператор присваивания для вашего класса Matrix4d и просто передавать это по кругу. Так будет меньше вероятность возникновения ошибок во время выполнения из-за плохого управления памятью или повреждения данных.

Ваш оператор () будет выглядеть так:

float& operator()( unsigned int xIndex, unsigned int yIndex )
{
  //return the right attribute
}

Вы будете вызывать его так для установки значений:

aMatrix(0,0) = 2.0;

или так для получения:

float attributeCopy = aMatrix(0,0);

Он работает в обоих направлениях.

EDIT: Забыл, что оператор [] принимает только один аргумент. Замените оператор на оператор (), он же функциональный оператор.

3
ответ дан 13 December 2019 в 19:25
поделиться

Я могу придумать три варианта.

Первый - это возврат std :: vector, а не массива. Пользователь всегда может получить указатель на внутренний массив с помощью & v [0].

std::vector<float> Matric4d::getData() { 
  std::vector<float> d(16); 
  d[0]=_m00; 
  ... 
  return d;
}

Второй - возврат boost :: array. (Я думаю, что есть tr1 :: array из будущего стандарта C ++ 0x, если ваш компилятор поддерживает что-то подобное) Снова легко добраться до внутреннего массива.

Третий - самый хакерский, но может лучше, если вам нужна скорость. Если вы храните свои числа с плавающей запятой, вы можете просто вернуть указатель на первую запись. (Обратите внимание, что вам нужно быть осторожным с деталями вашего класса, иначе вы получите "неопределенное поведение". Однако многие / большинство / все компиляторы все равно будут "делать правильные вещи".) О, и вам нужно быть осторожным, поскольку указатель будет действителен только до тех пор, пока матрица все еще существует.

float * Matrix4d::getData() { return &_m00; }
1
ответ дан 13 December 2019 в 19:25
поделиться
  1. Не передавайте плавающие числа по ссылке const, передавайте их по значению.

  2. Я полагаю, вы хотите вернуть массив, чтобы можно было сделать индексацию? Тогда не возвращайте массив из класса матрицы. Вместо этого перегрузите оператор [] или что-то в этом роде.

  3. Также, я бы не использовал 16 переменных-членов, а использовал один массив. Это значительно упрощает индексацию.

Вот как я бы это сделал:

class Matrix4d
{
    float matrix[4][4];

public:

    Matrix4d(float m00, float m01, float m02, float m03,
             float m10, float m11, float m12, float m13,
             float m20, float m21, float m22, float m23,
             float m30, float m31, float m32, float m33)
    {
        matrix[0][0] = m00;
        matrix[0][1] = m01;
        matrix[0][2] = m02;
        matrix[0][3] = m03;
        matrix[1][0] = m10;
        matrix[1][1] = m11;
        matrix[1][2] = m12;
        matrix[1][3] = m13;
        matrix[2][0] = m20;
        matrix[2][1] = m21;
        matrix[2][2] = m22;
        matrix[2][3] = m23;
        matrix[3][0] = m30;
        matrix[3][1] = m31;
        matrix[3][2] = m32;
        matrix[3][3] = m33;
    }

    float* operator[](int i)
    {
        return matrix[i];
    }

    const float* operator[](int i) const
    {
        return matrix[i];
    }
};

int main()
{
    Matrix4d test(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 16);
    test[3][2] = 15;
}
4
ответ дан 13 December 2019 в 19:25
поделиться

Вы можете использовать объединение для описания вашего класса.

union
{
    struct
    {
       float _m00;
       float _m01;
       ...
    };
    float _m[16];
};

Затем вы можете вернуть _m.

также получение cols может быть полезным, так:

union
{
    struct
    {
       float _m00;
       float _m01;
       ...
    };
    float _m[4*4];
    float _cols[4][4];
};
2
ответ дан 13 December 2019 в 19:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: