2010-08-28 1 views
1

Я следую примеру в Ускоренный C++ и написав простой класс Handle, который будет действовать как интеллектуальный указатель. Это использует virtual ctor idiom с использованием виртуальной функции clone(). Все идет нормально. Но что делать, когда я хочу использовать мой Handle для классов, которые я не контролирую, которые не предоставляют clone()?Как написать дескрипторы для классов, у которых нет члена clone()?

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

Моего вопрос: Это означает, что я должен написать версию clone() для каждого типа класса, который я себе представляю мой пользователь может использовать Handle с. Это кажется довольно сложным! Есть ли более элегантный и/или простой способ решить эту проблему? Как возможно, что такие вещи, как auto_ptr или boost :: shared_ptr, могут предоставить эту функциональность без утомительных определений clone()?

Для полноты, вот моя реализация Handle класса:

template <class T> class Handle 
{ 
public: 
    Handle() : p(0) {} 
    Handle(T* t) : p(t) {} 
    Handle(const Handle& s) :p(0) { if (s.p) p = s.p->clone(); } 
    const Handle& operator=(const Handle&); 
    ~Handle() { delete p; } 

    operator bool() { return p; } 

    T& operator*() { if (p) return *p; else throw std::runtime_error("Handle not bound"); } 
    T* operator->() { if (p) return p; else throw std::runtime_error("Handle not bound"); } 
private: 
    T* p; 
}; 

Спасибо!

+1

Использование clone() не очень похоже на C++. –

ответ

2

Решение этой проблемы состоит в том, чтобы просто не писать Handle s для этих классов. Нет. Действительно.

auto_ptr (устарел от C++ 11) никогда не должен клонировать базовый объект, потому что auto_ptr никогда не копирует объект. У auto_ptr только одна копия объекта, и когда копируется auto_ptr, управление объектом передается - этот объект не копируется.

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

shared_ptr никогда не должен клонировать, потому что он также контролирует только одну копию объекта. Копирование файла shared_ptr только увеличивает счетчик ссылок, и этот единственный объект уничтожается, когда счетчик ссылок равен нулю.

В общем случае, если нет возможности глубоко скопировать ресурс, контролируемый вашим классом, тогда вы должны просто сделать класс не подлежащим копированию. Если клиентам необходимо передать ссылки на ваш класс, они могут поместить класс в auto_ptr, unique_ptr или shared_ptr.