Поможет ли мне умный указатель повышения? - PullRequest
2 голосов
/ 09 июля 2010

Я использую Xerces для написания XML.

вот несколько строк, извлеченных из моего кода:

DOMLSSerializer *serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
serializer->release();

Есть ли интеллектуальный указатель для повышения, который я могу использовать, так чтоя могу избежать вызова serializer-> release ();как это не исключение безопасно.Проблема, как я вижу, состоит в том, что умные указатели могут вызывать delete только на вашем объекте указателя, может ли он быть настроен для вызова release?

спасибо

Ответы [ 4 ]

8 голосов
/ 09 июля 2010

Да, умные указатели могут вызывать пользовательский объект функции «удаления».

#include <iostream>
#include <tr1/memory>
struct Example {
    void release() { std::cout << "Example::release() called\n"; }
};
struct ExampleDeleter {
        void operator()(Example* e) { e->release(); }
};
int main()
{
        {
        std::tr1::shared_ptr<Example> p ( new Example, ExampleDeleter() );
        }
        std::cout << " see?\n";
}

(то же самое для наддува: см. shared_ptr (Y * p, D d); конструктор.)

3 голосов
/ 09 июля 2010

Да, boost::shared_ptr может использоваться с пользовательским функтором удаления (как показано Cubbi) или функцией удаления:

void my_deleter(DOMLSSerializer* s) {
    s->release();
}

// ...
boost::shared_ptr<DOMLSSerializer> serializer(foo->createLSSerializer(), my_deleter);
2 голосов
/ 09 июля 2010

Не знаю, почему люди так пишут свою собственную обертку @ Cubbi

В ответ на сделать общий птр не использовать delete

shared_ptr<DOMLSSerializer> serializer( 
  ((DOMImplementationLS*)implementation)->createLSSerializer(), 
  std::mem_fun(&DOMLSSerializer::release) );
0 голосов
/ 09 июля 2010

Если вам просто нужен крошечный класс RAII , вы можете написать вспомогательный класс самостоятельно.Он настолько мал, что едва тянет свой вес (не говоря уже о том, чтобы оправдать вытягивание библиотеки):

class DOMLSSerializerOwner {
public:
  DOMLSSSerializerOwner( DOMLSSerializer *serializer ) : m_serializer( serializer ) { }
  ~DOMLSSerializerOwner() { m_serializer->release(); }

  operator DOMLSSerializer*() { return m_serializer; }

private:
  DOMLSSerializerOwner( const DOMLSSerializerOwner &other ); // disabled
  void operator=( const DOMLSSerializerOwner &rhs ); // disabled

  DOMLSSerializer *m_serializer;
};

Тогда вы можете заставить свой код читать:

void f()
{
  DOMLSSerializerOwner serializer = ((DOMImplementationLS*)implementation)->createLSSerializer();
  serializer->doThis();
  serializer->doThis();
  // Look Ma: no release() call; 'serializer' does it automatically when going out of scope
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...