2013-02-19 2 views
3

Насколько я знаю, указатель void в C++ void* может указывать на что угодно. Это может быть очень полезно (для меня), если я хочу разработать решение, не используя какое-то наследование. Но вопрос, который я хочу знать, - есть ли недостатки производительности в этом подходе?Недостатки указателя void в C++

+4

Какие недостатки в производительности? Это просто указатель, похожий на указатель на другие типы. Из описания вашей реализации кажется, что вы пытаетесь решить проблему C++ с помощью методов C, которых не следует. Если вы хотите, чтобы наследование использовало наследование не 'void *'. –

+3

Основная проблема заключается в том, чтобы выяснить, что она на самом деле указывает, чтобы правильно отбросить ее. И если вы ошибаетесь, вам повезло, если вы сразу заметите ошибки. – aschepler

+3

Не будет недостатков в производительности, но вы потеряете всю информацию о типе (и, таким образом, введите безопасность). Это означает, что компилятор не сможет обнаружить ошибки, которые он мог бы в противном случае, и вы столкнетесь с ними во время выполнения (подумайте о неопределенных ошибках и труднодоступных ошибках). – Angew

ответ

9

Самый большой недостаток заключается в том, что использование указателей void останавливает компилятор от возможности проверки типа. Особенно на языке, который поддерживает объектно-ориентированные принципы, я думаю, было бы странно использовать тяжелые указатели.

Скорее всего, вы найдете указатели void в C, чтобы имитировать какое-то полиморфное поведение, но существуют те же проблемы безопасности типов.

+1

+1 для указания точки зрения компилятора – LihO

0

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

1

void* может указывать на что угодно. Это может быть весьма полезным (для меня), если я хочу, чтобы разработать решение без использования какого-того наследования

Если вы думаете о переходе на void* указатель на какую-либо функцию, думаю уже о том, как он будет использоваться , Чтобы вызвать метод на этом объекте или получить доступ к его членам, вам все равно нужно знать тип этого объекта.

Используйте void*, только если вам действительно нужно. Если вы ищете способ обработки объектов более общим образом, то просто пойдите для правильной разработки OO. Когда у вас есть указатель void*, единственное, что вы знаете, это то, что «есть что-то по этому адресу в памяти», не более того.

Показатели использования указателей void* такие же, как с любыми другими указателями. безопасности, понятность, а также с ней связаны расширяемость и ремонтопригодность вашего кода должны быть ваши проблемы.

1

Возможно, все еще существуют платформы, где void* больше, чем другие типы указателей, или имеют другой формат, поэтому отливка от или от void* превращается в фактический код преобразования. На общем оборудовании (x86, ARM) это не так, поэтому нет проблем с производительностью с void* - вы просто отказываетесь от типа безопасности.

4

Недостаток производительности при использовании void* отличается от того факта, что компилятор не может делать предположений о типе, на котором он указывает. Он по-прежнему является указателем, как и любой другой.

A void* был полезен в C для указания на какой-либо произвольный тип, потому что любой указатель на объект типа может быть преобразован в void*. Однако выполнение почти ничего с ним приведет к неопределенному поведению. Вы можете только надежно вернуть его к исходному типу указателя.

Однако в C++ у нас есть намного лучший способ хранения указателя на некоторые произвольные шаблоны типов. Для некоторого аргумента шаблона T мы можем иметь T*.

+1

«Правильно» может быть правильным, но не полезным. Я бы использовал слово «тот же» или «оригинал». –

+0

+5 за сказанное о ** шаблоны **. – Destructor

5

Есть два серьезных недостатка производительности void*. первого том, что это делает его гораздо более трудно понять и поддерживать программу, которая оказывает серьезное влияние на производительности программистов обслуживания — и на время выполнения, так как это делает переделки программного обеспечения более сложным когда профилировщик показывает, где у вас проблемы с производительностью. Самые быстрые программы - это те, которые хорошо написаны в первую очередь, , так как тогда становится возможным сделать локальные оптимизации в критическим местам без необходимости переписывать всю программу .

Второе воздействие на производительность: void* может содержать псевдоним . Правильный анализ псевдонимов является важной частью оптимизации компилятора , и все, что вы делаете, чтобы сделать это более сложным, затрудняет оптимизатор и может привести к более медленному коду. (char* и unsigned char* имеют аналогичный эффект.)

+0

+1 для переориентации очевидной проблемы как проблемы с производительностью. –

0

Да - у вас могут быть некоторые недостатки в производительности. Используя 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).

More about strict aliasing

+0

Возможно, вы имели в виду * что-то делать с param2, param1 не использовался * –

+0

Нет. Я имел в виду то, что написал. –