2016-02-04 2 views
4

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

Вот пример, когда оригинальный умный указатель теряет право собственности.

int main(int argc, char* argv[]) 
{ 
    std::unique_pointer<pcap_if_t> object; 

    auto object_pointer = object.get(); 
    pcap_findalldevs(&object_pointer, ...); // The unique_ptr loses ownership after being passed to the function 
} 

Как бы это осуществить, без первоначального умного указателя, теряющего право собственности на указатель?

EDIT:
Функция Я звоню это pcap_findalldevs в Libpcap. Я боюсь, что эта функция может стать причиной потери собственности.
Я обновил свой пример кода, чтобы отразить то, что я на самом деле делаю.

+1

До тех пор, пока 'some_function' не получает права собственности на указатель, который вы передаете, или указатель, который указывает на то, что вы делаете, вероятно, просто отлично. –

+0

Использование 'std :: move', вы пробовали? – dlmeetei

+0

@Deleisha Что именно вы могли бы _move_ это? Другой 'std :: unique_ptr'? –

ответ

6

Функция, которая принимает указатель на указатель, как правило, делает это потому, что он может изменить его, и pcap_findalldevs действительно делает это. И этот указатель должен быть выпущен с вызовом pcap_freealldevs.

Таким образом, ваш лучший выбор unique_ptr с пользовательскими Deleter aquiring собственность из необработанного указателя:

struct pcap_deleter 
{ 
    void operator()(pcap_if_t* ptr) 
    { 
     pcap_freealldevs(ptr); 
    } 
}; 

//... 
using pcap_ptr = std::unique_ptr<pcap_if_t, pcap_deleter> 
pcap_ptr get_devs() { 
    pcap_if_t* object_pointer; 
    pcap_findalldevs(&object_pointer, ...); 
    return pcap_ptr(object_pointer); 
} 

//... 

auto object = get_devs(); 
3

Вот пример, когда оригинальный умный указатель теряет право собственности.

Nope. Unique_ptr сохраняет право собственности после вызова get()

unique_ptr потеряет право собственности после вызова release()

ссылка: http://en.cppreference.com/w/cpp/memory/unique_ptr

1

Вам не нужно ничего из этого. Это правильная последовательность вызова:

pcap_if_t ip = nullptr; 
res = pcap_findalldevs(&ip, errbuf); 
// now ip (hopefully) points to something 

Там нет места для смарт-указатель на что-нибудь перед Зов. Теперь после вызов, который вы можете назначить ip на какой-то умный указатель. Не забывайте, что пользовательский делетер вам понадобится.

Обратите внимание, что ip на самом деле указывает на связанный список, реализованный с помощью простых необработанных немых честных указателей, которые вы не можете изменить. Утилита умного указателя на голову списка в лучшем случае сомнительна. Вероятно, было бы целесообразно скопировать информацию в подходящий контейнер C++ и удалить связанный список сразу после вызова.