указатели кастинга - PullRequest
       28

указатели кастинга

0 голосов
/ 28 июня 2010

Я использую ptr_map для хранения различных типов указателей.

boost::ptr_map<string, any> someMap;

Я храню там несколько шаблонных объектов класса:

someMap.insert("1", new SomeClass<int>());
someMap.insert("2", new SomeClass<float>());

Теперь я хочу получить значения с карты. Вот образец со ссылками:

template<typename T>
T &get(const string &someKey)
{
    try
    {
        return any_cast<EventType&>(mSignalAssociation.at(signalName));
    } catch(bad_any_cast &e)
    {
        // Logging here
    }
}

get< SomeClass<int> >("1"); // This works

Но мне не нравятся ссылки, потому что я не могу вернуть, например, NULL, если приведение неверно или объект не существует.

Как я могу получить указатель с этой карты?

T *get(const string &someKey)
{
   return any_cast<EventType*>(mSignalAssociation.at(signalName));
}

Это строит, но не на касте, почему?

Ответы [ 3 ]

1 голос
/ 28 июня 2010

Функция any_cast

Если передан указатель, он возвращает аналогичный квалифицированный указатель на содержимое значения в случае успеха, в противном случае возвращается значение null.Если T является ValueType, он возвращает копию удерживаемого значения, в противном случае, если T является ссылкой на (возможно, const квалифицированное) ValueType, он возвращает ссылку на удерживаемое значение.

Что вы хотитесемантика указателяТакже прекратите использовать ptr_map, это пустая трата, как было указано в комментариях.

map<string, any> someMap;
someMap["1"] = SomeClass<int>();
someMap["2"] = SomeClass<float>();

// this will be a valid pointer because someMap["1"] stores 
// an object of SomeClass<int>
SomeClass<int>* valid_ptr = any_cast<SomeClass<int> >(&someMap["1"]);

// this will be null pointer because someMap["2"] doesn't store
// an object of SomeClass<int>
SomeClass<int>* invalid_ptr = any_cast<SomeClass<int> >(&someMap["2"]);

Если вам нужно по какой-то причине хранить указатели на эти объекты SomeClass, то я думаю, что вам придется сделатьУправляйте памятью самостоятельно (вручную освобождайте элементы, хранящиеся в любом) и используйте дополнительный уровень косвенности для обнаружения ошибок приведения с нулевым указателем.Вероятно, лучше использовать что-то вроде boost :: shared_ptr, если вы это сделаете.

map<string, any> someMap;
someMap["1"] = new SomeClass<int>();
someMap["2"] = new SomeClass<float>();

// this will be a valid pointer because someMap["1"] stores 
// an object of SomeClass<int>*
SomeClass<int>** valid_ptr = any_cast<SomeClass<int>*>(&someMap["1"]);

// this will be a null pointer because someMap["1"] does
// not store an object of SomeClass<int>*
SomeClass<int>** invalid_ptr = any_cast<SomeClass<int>*>(&someMap["2"]);
1 голос
/ 28 июня 2010

как насчет этого:

T *get(const string &someKey)
{
   return &any_cast<EventType&>(mSignalAssociation.at(signalName));
}

(Просто предположение)

0 голосов
/ 29 июня 2010

Но я не люблю ссылки, потому что я не может вернуть, например, NULL, если кастинг плохой или объект не есть

Ах ... так вот почему вы выполняете эту гимнастику с указателями, ссылками, кастами и контейнерами для управления памятью! :)

Как я уже говорил ранее ; это создаст ненужные головные боли. К счастью, ваша проблема была решена - просто посмотрите на Boost.Optional .

...