Пересылка shared_ptr без объявления класса - PullRequest
11 голосов
/ 29 июня 2011

ПРИМЕЧАНИЕ : я обнаружил, что источник ошибки на самом деле не имеет отношения к shared_ptr, а просто умно замаскирован как таковой в сообщении об ошибке. Таким образом, нижеследующее - это в основном ерунда (не ответы, они в порядке)

-

У меня возникли проблемы с использованием shared_ptr (в настоящий момент повышение), когда мне нужно просто перенаправить указатель на другую функцию. При использовании нативных указателей промежуточная функция не должна иметь доступа к определению класса, но при использовании smart_ptr оказывается, что это так. Есть ли способ избежать этого?

Например, заданная целевая функция:

void func( shared_ptr<SomeClass> const & obj )

const & решает часть проблемы, но, скажем, у нас есть класс-получатель, который получает объект для какого-то другого класса, например:

shared_ptr<SomeClass> someClassInstance();

А вот где я хотел бы просто собрать аргументы и перейти к целевой функции:

func( someClassInstance() );

С простым указателем эта точка в коде может просто использовать прямое объявление SomeClass, но с smart_ptr оно должно иметь полное определение (предположительно, поскольку smart_ptr может потребоваться удалить класс).

Теперь, если someClassInstance вернет const &, эта проблема на самом деле исчезнет, ​​поскольку промежуточный код не будет копировать какие-либо объекты. Однако функция получения должна возвращать копию из соображений безопасности потока.

Могу ли я в любом случае добиться такой переадресации параметров интеллектуального указателя без определения класса? То есть можно ли использовать интеллектуальные указатели таким же образом, как и традиционные указатели в этих обстоятельствах.

-

ОБНОВЛЕНИЕ : Написание небольшого теста дает правильные ответы, что достаточно предварительной декларации. Тем не менее, GCC все еще жалуется в одной ситуации. Я собираюсь выяснить, что именно вызывает его сбой (в данной конкретной ситуации).

Я сейчас закрываю этот вопрос или как?

Ответы [ 3 ]

14 голосов
/ 29 июня 2011

Вам нужно как минимум предварительное объявление для T для каждого упоминания shared_ptr<T>.

Только если вы используете одинарные shared_ptr::operator* и shared_ptr::operator->, нужна полная вещь.Под капотом shared_ptr используется смесь полиморфизма времени компиляции и времени исполнения, что делает это возможным.См. Также этот вопрос , чтобы узнать о "магии".

Пример:

// frob.h
#ifndef FROB_H
#define FROB_H

#include <shared_ptr>

class Foo;
void grind (std::shared_ptr<Foo>);

#endif

Обратите внимание, что канонический способ передачи shared_ptr является значением (т. Е.удалить const&).

3 голосов
/ 29 июня 2011

Да, совместно используемые указатели специально предназначены для работы с неполными типами (убойная особенность IMO). Они требуют только предварительного объявления класса, а не определения класса. Из документации Boost :

Обратите внимание, что scoped_ptr требует, чтобы T был полным типом во время уничтожения, а shared_ptr - нет.

Вы можете найти обсуждение того, как это работает здесь .

Поскольку общие указатели должны работать с неполными типами, можете ли вы дать нам конкретный (минимальный) пример, в котором это не работает для вас?

0 голосов
/ 08 августа 2018

Кажется, что явное предварительное объявление не всегда требуется:

using PtrX = std::shared_ptr<class X>;
using PtrW = std::weak_ptr<X>;

Здесь class X внутри аргумента шаблона происходит волшебство.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...