Это теоретический вопрос для C и C ++.
У меня есть тип матрицы 4×4, который определяется довольно просто:
typedef float Matrix44[16];
У меня также есть много методов, которые принимают Matrix44
в качестве параметра, например:
bool matrixIsIdentity(Matrix44 m);
У меня также есть специальная схема выделения памяти, при которой большая область памяти предварительно выделяется в куче, а затем я управляю выделением в этой предварительно выбранной памяти вручную. Как таковой я заменил / перегружен malloc
/new
с моими собственными реализациями. Проблема в том, как на заказ malloc
а также new
по своей природе возвращаем указатель, а не объект.
Обычно я просто делал бы следующее:
// Method 1
1] Matrix44 mat = { ... };
2] bool res = matrixIsIdentity(mat);
Тем не менее, строка 1 выделена mat
в стеке, а не в моей области памяти, как я хотел бы. Альтернатива:
// Method 2
1] Matrix44 *mmat = myMalloc(...);
1a] Matrix44 *nmat = new ...
2] bool res = matrixIsIdentity(*mat);
Проблема здесь в том, что мне придется засорять мой код операторами разыменования. Теперь один вариант будет переписать все методы, чтобы принять Matrix44*
вместо этого, но, поскольку это теоретически, я хотел бы предположить, что это не вариант.
Поэтому мой вопрос: есть ли способ объявить автоматическую переменную в C и / или C ++, как в Method 1 Line 1
, но следуйте альтернативной схеме распределения (как в Method 2 Line 1
)?
(Я ценю, что это может включать обсуждение, связанное с компилятором, но я не добавил тегов на этот счет)
Это невозможно, автоматические переменные основаны на стеке. Но вы можете делать все что угодно внутри конструктора. Таким образом, ваш Matrix44 будет просто тонкой оболочкой, скажем, Matrix44Impl, которая будет указывать на вашу «пользовательскую» память.
Ну, это не на 100% точно, что вы просите, но с помощью ссылки будет выглядит как то, что вы хотите, и вести себя более или менее неотличимо от того, что вы хотите, если я правильно понимаю:
Matrix44& mmat = *new Matrix44(...); // or *myMalloc() or whatever
mmat.Rotate(45.0);
bool res = matrixIsIdentity(mat);
...
delete &mmat; // or myFree(&mmat) or something similar
Обратите внимание на разыменование на new
и адрес оператора на delete
что по общему признанию немного странно, но я не понимаю, почему это было бы синтаксически / семантически неправильно. Компилятор тоже хорошо это воспринимает, и он «работает».
Я бы настоятельно рекомендовал не делать таких вещей. Даже если это «работает» на отлично, это вводит в заблуждение. Код должен выглядеть так, как он работает, и так же, как он выглядит. Этот код не
Что-то, что похоже его жизнь в стеке не должна (или даже возможна!) передаваться delete
и, возможно, код, который делает что-то странное, на самом деле не «работает», даже если он «работает нормально».