Перенаправление shared_ptr без объявления класса
ПРИМЕЧАНИЕ. Я обнаружил, что источник ошибки на самом деле не связан с shared_ptr, просто искусно замаскированным под таким сообщением в сообщении об ошибке. Таким образом, нижеследующее в основном абсурд (а не ответы, они в порядке)
-
У меня возникли проблемы с использованием shared_ptr
(boost на данный момент), где мне нужно просто переслать указатель на другую функцию. Используя собственные указатели, промежуточная функция не нуждается в доступе к определению класса, но, используя smart_ptr, похоже, что это так. Есть ли способ избежать этого?
Например, заданная целевая функция:
void func( shared_ptr<SomeClass> const & obj )
const &
заботится о части проблемы, но скажем, что у нас есть класс-геттер, который получает объект для другого класса, например:
shared_ptr<SomeClass> someClassInstance();
И здесь я хочу просто собрать аргументы и перейти к целевой функции:
func( someClassInstance() );
С помощью простого указателя эта точка в коде может просто использовать объявление вперед SomeClass
, но с smart_ptr
оно должно иметь полное определение (предположительно, поскольку smart_ptr, возможно, потребуется удалить класс).
Теперь, если someClassInstance
должен был вернуть const &
, эта проблема действительно исчезнет, так как промежуточный код не будет копировать какие-либо объекты. Тем не менее, функция getter должна возвращать копию для соображений безопасности потока.
В любом случае я могу достичь этого типа перенаправления параметров интеллектуального указателя, не требуя определения класса? То есть я могу использовать интеллектуальные указатели таким же образом, как и традиционный указатель в этом случае.
-
ОБНОВЛЕНИЕ. Написав небольшой тест, ответы правильны, что достаточно прямого объявления. Тем не менее GCC по-прежнему жалуется в одной ситуации. Мне нужно будет выяснить, что именно заставляет его потерпеть неудачу (в этой конкретной ситуации).
Я закрываю этот вопрос сейчас или что?
Ответы
Ответ 1
Для каждого упоминания shared_ptr<T>
вам нужно, по крайней мере, объявление вперед для T
.
Только если вы используете унарные shared_ptr::operator*
и shared_ptr::operator->
, вам нужна полная вещь. Под капотом shared_ptr
используется комбинация compiletime- и runtime-полиморфизма, что делает возможным это. См. Также этот вопрос, чтобы узнать о "волшебстве".
Пример:
// frob.h
#ifndef FROB_H
#define FROB_H
#include <shared_ptr>
class Foo;
void grind (std::shared_ptr<Foo>);
#endif
Обратите внимание, что канонический путь передачи shared_ptr
равен значению (т.е. удаляет const&
).
Ответ 2
Да, общие указатели специально разработаны для работы с неполными типами (функция убийцы IMO). Они требуют только прямого объявления класса, а не определения класса. Из Boost documentation:
Обратите внимание, что scoped_ptr требует, чтобы T был полным типом во время уничтожения, но shared_ptr этого не делает.
Вы можете найти обсуждение того, как это работает здесь.
Поскольку общие указатели должны работать с неполными типами, можете ли вы дать нам конкретный (минимальный) пример, в котором это не работает для вас?