Как создать ссылку на smart_pointer? - PullRequest
0 голосов
/ 09 января 2020
std::ofstream x; 
std::ostream *foo = NULL; 
x.open(...); 
foo = &x; 
std::ostream *bar = diff? foo2() : foo; //foo2 is a function returning a new std::ostream(...) and has no side effects
std::ostream &bar1 = *foo; 
std::ostream &bar2 = *bar; 

Здесь bar - это выборочно указатель, который не требует удаления (foo), или указатель, созданный с использованием new, который необходимо удалить (foo2()).

Я хочу сделать bar умным указателем (вероятно, здесь имеет смысл shared_ptr), поэтому мне не нужно явно обрабатывать удаление в случае, если ему присвоен результат foo2.

Однако это подразумевает, что я также делаю foo (и возвращаю foo2) shared_ptr, потому что если я этого не сделаю, я получу ошибку

free(): invalid pointer
free(): invalid pointer

.

std::shared_ptr<std::ostream> foo2(..) {
   ...
   std::shared_ptr<std::ostream> ptr(new std::ofstream(...));
   return ptr;
}

...

std::ofstream x; 
std::shared_ptr<std::ostream> foo(nullptr); 
x.open(...); 
foo.reset(&x); 
std::shared_ptr<std::ostream> bar(diff? foo2() : foo); 
std::ostream &bar1 = *foo; 
std::ostream &bar2 = *bar; 

Теперь я получаю это ошибка -

munmap_chunk(): invalid pointer
free(): invalid pointer

На первый взгляд, я думаю, что создание bar1 и bar2 shared_ptrs может решить проблему, но я не уверен, как это сделать, учитывая, что bar1 и bar2 являются ссылками на foo и bar. Может ли кто-нибудь помочь мне с этим, пожалуйста?

1 Ответ

1 голос
/ 09 января 2020

строка - это выборочно указатель, который не нужно удалять ... или указатель ... который нужно удалить

Я хочу сделать панель умным указателем

Это плохой дизайн. Лучше использовать безусловно владеющий или безусловно не владеющий указатель, а не условно один или другой.

Я предлагаю переместить все, что использует ostream, в отдельную функцию и просто вызвать это одним потоком или другое:

void use_stream(std::ostream&);

if (diff) {
    auto ptr = foo2(); // some flavour of smart pointer
                       // use unique if you don't need shared
    use_stream(*ptr);
} else {
    std::ofstream foo(...);
    use_stream(foo);
}

Однако предпочтительно возвращать поток по значению из foo2, если только у вас нет какой-либо причины динамического c полиморфизма для использования косвенного обращения.

...