GMP и умные указатели - PullRequest
       2

GMP и умные указатели

0 голосов
/ 26 октября 2010

Я работаю с gnump и имею функцию, которая должна возвращать mpz_t.Поэтому я должен использовать необработанные указатели для возврата значения.Я выделяю пространство с new для указателя и отправляю его в качестве параметра в моей функции.

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

shared_ptr<mpz_t> func()
{
    mpz_t z;
    mpz_init_set_str(z, "23423423423", 10);

    shared_ptr<mpz_t> p /* Shall I allocate space with "new" or smth else?.. */

    return p;
}

Буду признателен за любой пример.

Ответы [ 3 ]

5 голосов
/ 26 октября 2010

Использование общих указателей в этом контексте вам не поможет. Сам тип mpz_t подобен указателю. Такой указатель инициализируется путем вызова любой из функций mpz_init _... Однако вам нужно вызвать mpz_clear, чтобы освободить пространство, выделенное функцией init, которую вы использовали.

Сохранение указателя в shared_ptr не дает желаемого эффекта. Он отслеживает количество ссылок на вашу переменную mpz_t и также удаляет переменную mpz_t, когда на нее больше нет ссылок. Однако это освобождает только переменную mpz_t, которая похожа на указатель. Он не вызывает функцию mpz_clear.

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

GNU MP предлагает интерфейс класса C ++. (Ищите mpz_class)

shared_ptr<mpz_class> func()
{
  shared_ptr<mpz_class> z(new mpz_class("23423423423", 10));
  return z;
}

Если вам нужно передать mpz_t другим функциям, вы можете получить его из общего указателя:

p->get_mpz_t()

где p имеет тип shared_ptr .

1 голос
/ 26 октября 2010

Вы можете создать пользовательское средство удаления, которое будет вызываться умным указателем, хотя для него требуется тип указателя. Если вы хотите использовать mpz_t вместо указателя и использовать mpz_clear для уничтожения, вы можете написать свою обертку для этого или даже реализовать ее самостоятельно, хотя вы не можете напрямую использовать shared_ptr, который ожидает указатель.

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

1 голос
/ 26 октября 2010

если вы хотите вернуть z без копирования, это будет


shared_ptr func()
{
    shared_ptr z(new mpz_t());
    mpz_init_set_str(*z, "23423423423", 10);

    return z;
}
...