C ++, как определить оператор приведения, который не копирует данные? - PullRequest
1 голос
/ 12 марта 2012

хорошо - возможно, это глупый вопрос, и операторы приведения делают это уже по своей природе ..

Что у меня есть:

  • некоторое внешнее определение класса матрицы 4x4

  • некоторый собственный класс Matrix 4x4

оба класса просто хранят число с плавающей запятой [16];

Мне бы хотелосьопределить в своем классе Matrix оператор приведения, чтобы я мог делать такие вещи, как:

MyMatrix4x4 m;
OtherMatrix4x4(m).someFunctionDefinedInOtherMatrix4x4();
SomeFunctionThatTakesOtherMatrix4x4(OtherMatrix4x4(m));

И я не хочу, чтобы этот оператор копировал какие-либо данные - функции должны просто работать с одним и тем же плавающей точкой [16] data

Как это сделать?

Ответы [ 3 ]

3 голосов
/ 12 марта 2012

И я не хочу, чтобы этот оператор копировал какие-либо данные - функции должны просто работать с теми же данными с плавающей точкой [16]

Я не хочу создавать какие-либо данные в куче,хочу, чтобы это работало со значениями в стеке, а также для удобства я хотел бы иметь оператор приведения

Ну, этого не произойдет.Правила псевдонимов C ++ в значительной степени запрещают это.

Вы можете использовать приведение указателей, чтобы сделать «притворяться, что это что-то другое», но вы не можете использовать приведение объектов для этого.Вы можете привести указатель к объекту стека к указателю на тип вашего объекта:

MyMatrix4x4 m;
OtherMatrix4x4 * o = (OtherMatrix4x4 *) &m;

Однако есть две проблемы.Во-первых, o будет длиться только столько, сколько m.Это не объект;это указатель на другой объект.Во-вторых, это (в общем) неопределенное поведение (частично из-за нарушения псевдонимов: перекрытие двух несвязанных типов).О, есть вероятность, что это сработает.Но вы не в курсе того, что гарантирует C ++.

Это пахнет преждевременной оптимизацией.Вы действительно думаете, что копирование 16-ти чисел является , что является большой проблемой производительности?Если это так, то почему бы просто не использовать OtherMatrix4x4 в своем коде вместо MyMatrix4x4?

1 голос
/ 12 марта 2012
OtherMatrix4x4(m)

Это не оператор приведения, это конструктор преобразования .

Предположим, что следующее определение MyMatrix4x4:

struct MyMatrix4x4
{
    float x[16];
};

следующее должно сделать это:

struct OtherMatrix4x4
{
    float* x;
    OtherMatrix4x4(MyMatrix4x4& other)
    {
       x = other.x;
    }
    void foo()
    {
       x[0] = 0;
    }
};

Для проверки:

MyMatrix4x4 a = {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}};
OtherMatrix4x4(a).foo();
cout << b.x[0]; //will output 0, not 1

РЕДАКТИРОВАТЬ Вот версия, в которой вы не можете редактировать другую матрицу:

struct OtherMatrix4x4
{
    float x[16];
    void foo()
    {
        x[0] = 0;
    }
};

struct MyMatrix4x4
{
    float* x;
    operator OtherMatrix4x4()
    {
        OtherMatrix4x4 other;
        x = other.x;
        return other;
    }
};

MyMatrix4x4 m;
OtherMatrix4x4(m).foo();
0 голосов
/ 12 марта 2012

Просто чтобы представить другое решение, представляющее наследование.Это позволит использовать код, который вы разместили выше.Однако это не оператор приведения.

class MyMatrix4x4 {
public:
    float f;
};

class OtherMatrix4x4 : MyMatrix4x4  {
public:
    OtherMatrix4x4(MyMatrix4x4 &matrix)
    {
        f = matrix.f;
    }

    void someFunctionDefinedInOtherMatrix4x4();
};
...