Почему `boost :: any` лучше, чем` void * `? - PullRequest
14 голосов
/ 06 января 2012

Какие присущие преимущества дают boost::any и boost::any_cast по сравнению с использованием void* и dynamic_cast?

Ответы [ 4 ]

22 голосов
/ 06 января 2012

Преимущество состоит в том, что boost::any намного более безопасен для типов, чем void*.

* 1005 Е.Г. *

int i = 5;
void* p = &i;
static_cast<double*>(p);  //Compiler doesn't complain. Undefined Behavior.
boost::any a;
a = i;
boost::any_cast<double>(a); //throws, which is good

Что касается вашего комментария, вы не можете dynamic_cast из void*. Вы можете dynamic_cast только из указателей и ссылок на типы классов, которые имеют хотя бы одну виртуальную функцию (или полиморфные типы)

13 голосов
/ 06 января 2012

boost::any вызывает деструкторы:

{
    boost::any x = std::string("Hello, world");
    x = std::wstring(L"Goodbye"); // string::~string called here
} // wstring::~wstring called here
6 голосов
/ 25 января 2012

почему-то никто не упомянул, что boost :: any <> действует как тип значения, а void * - указатель.Это означает, что любой <> может хранить ЛЮБОЙ объект ЛЮБОГО размера.После сохранения вы можете передать переменную любого типа <> куда угодно;он живет сам по себе.

С другой стороны, void * имеет размер указателя, поэтому вы должны либо убедиться, что sizeof (ваши данные) <= sizeof (void *) или ваш void * простоуказатель на реальные данные, которые хранятся где-то еще.Но в этом случае он полностью отличается от любого <>, потому что теперь вам нужно беспокоиться об этом «где-то еще» и убедиться, что он остается действительным, пока действует void *, что иногда может стать проблемой, особенно в многопоточных приложениях.

Кроме того, как уже упоминалось, любой <> очень безопасен для типов, он будет хранить все, что вы захотите, но единственный способ вернуть его - узнать точный тип или он потерпит неудачу (что может быть своего родараздражает, когда один API дает вам без знака int и ваш код хочет, чтобы int обрабатывались как разные типы).void * позволит вам делать с ней все, что вы захотите, и если вы начнете читать или обрабатывать кучу и / или неинициализированную память, это не остановит вас и даже не даст вам знать, что вы делаете это.

5 голосов
/ 06 января 2012

Вот что говорит Буст:

Поддерживает копирование любого типа значения и безопасное извлечение извлеченных это значение строго против его типа.

Ни то, ни другое не может быть сделано с void*. Для вас нет чеков, и вы должны сами знать, на что вы можете их разыграть.

Я не думаю, что dynamic_cast вообще входит в картину, так как она не имеет к этому никакого отношения.

...