недостатки указателя void в C++ [закрыт]


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

7 3

7 ответов:

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

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

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

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

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

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

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

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

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

Подробнее о строгом сглаживании

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

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

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

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

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