Насколько я знаю, указатель void в C++ void*
может указывать на что угодно. Это может быть очень полезно (для меня), если я хочу разработать решение, не используя какое-то наследование. Но вопрос, который я хочу знать, - есть ли недостатки производительности в этом подходе?Недостатки указателя void в C++
ответ
Самый большой недостаток заключается в том, что использование указателей void останавливает компилятор от возможности проверки типа. Особенно на языке, который поддерживает объектно-ориентированные принципы, я думаю, было бы странно использовать тяжелые указатели.
Скорее всего, вы найдете указатели void в C, чтобы имитировать какое-то полиморфное поведение, но существуют те же проблемы безопасности типов.
+1 для указания точки зрения компилятора – LihO
Я не понимаю, почему возникли проблемы с производительностью при использовании указателя void, а не любого другого указателя. Я буду больше заботиться о безопасности, которую вы отказываетесь от указателя пустоты.
void*
может указывать на что угодно. Это может быть весьма полезным (для меня), если я хочу, чтобы разработать решение без использования какого-того наследования
Если вы думаете о переходе на void*
указатель на какую-либо функцию, думаю уже о том, как он будет использоваться , Чтобы вызвать метод на этом объекте или получить доступ к его членам, вам все равно нужно знать тип этого объекта.
Используйте void*
, только если вам действительно нужно. Если вы ищете способ обработки объектов более общим образом, то просто пойдите для правильной разработки OO. Когда у вас есть указатель void*
, единственное, что вы знаете, это то, что «есть что-то по этому адресу в памяти», не более того.
Показатели использования указателей void*
такие же, как с любыми другими указателями. безопасности, понятность, а также с ней связаны расширяемость и ремонтопригодность вашего кода должны быть ваши проблемы.
Возможно, все еще существуют платформы, где void*
больше, чем другие типы указателей, или имеют другой формат, поэтому отливка от или от void*
превращается в фактический код преобразования. На общем оборудовании (x86, ARM) это не так, поэтому нет проблем с производительностью с void*
- вы просто отказываетесь от типа безопасности.
Недостаток производительности при использовании void*
отличается от того факта, что компилятор не может делать предположений о типе, на котором он указывает. Он по-прежнему является указателем, как и любой другой.
A void*
был полезен в C для указания на какой-либо произвольный тип, потому что любой указатель на объект типа может быть преобразован в void*
. Однако выполнение почти ничего с ним приведет к неопределенному поведению. Вы можете только надежно вернуть его к исходному типу указателя.
Однако в C++ у нас есть намного лучший способ хранения указателя на некоторые произвольные шаблоны типов. Для некоторого аргумента шаблона T
мы можем иметь T*
.
«Правильно» может быть правильным, но не полезным. Я бы использовал слово «тот же» или «оригинал». –
+5 за сказанное о ** шаблоны **. – Destructor
Есть два серьезных недостатка производительности void*
. первого том, что это делает его гораздо более трудно понять и поддерживать программу, которая оказывает серьезное влияние на производительности программистов обслуживания — и на время выполнения, так как это делает переделки программного обеспечения более сложным когда профилировщик показывает, где у вас проблемы с производительностью. Самые быстрые программы - это те, которые хорошо написаны в первую очередь, , так как тогда становится возможным сделать локальные оптимизации в критическим местам без необходимости переписывать всю программу .
Второе воздействие на производительность: void*
может содержать псевдоним . Правильный анализ псевдонимов является важной частью оптимизации компилятора , и все, что вы делаете, чтобы сделать это более сложным, затрудняет оптимизатор и может привести к более медленному коду. (char*
и unsigned char*
имеют аналогичный эффект.)
+1 для переориентации очевидной проблемы как проблемы с производительностью. –
Да - у вас могут быть некоторые недостатки в производительности. Используя void *
, вы можете отключить оптимизацию, основанную на предположении о строгом псевдонижении.
Пример
void fun(void * param1, int & param2)
{
param2 = 7; // 1
// do something with param1, param2 not used
param2 += 1; // 2
}
Если не было void *
переменная, компилятор может удалить задание 1 и 2 просто генерируют param2 = 8
. Но теперь это невозможно, потому что param1
может указывать на param2
, если вы позвонили fun(&i, i)
.
Возможно, вы имели в виду * что-то делать с param2, param1 не использовался * –
Нет. Я имел в виду то, что написал. –
Какие недостатки в производительности? Это просто указатель, похожий на указатель на другие типы. Из описания вашей реализации кажется, что вы пытаетесь решить проблему C++ с помощью методов C, которых не следует. Если вы хотите, чтобы наследование использовало наследование не 'void *'. –
Основная проблема заключается в том, чтобы выяснить, что она на самом деле указывает, чтобы правильно отбросить ее. И если вы ошибаетесь, вам повезло, если вы сразу заметите ошибки. – aschepler
Не будет недостатков в производительности, но вы потеряете всю информацию о типе (и, таким образом, введите безопасность). Это означает, что компилятор не сможет обнаружить ошибки, которые он мог бы в противном случае, и вы столкнетесь с ними во время выполнения (подумайте о неопределенных ошибках и труднодоступных ошибках). – Angew