2012-01-10 3 views
3

Можно ли использовать std :: tr1 :: shared_ptr, как в примере кода, безопасно и правильно, для подсчета ссылок? (Это просто конкретный пример, класс может содержать что-нибудь еще (Недействительными *) вместо FILE *)с использованием std :: tr1 :: shared_ptr как внутренний механизм подсчета ссылок

class File 
{ 
public: 
    File(const char* path, const char* mode) : 
     _refcount(new int(0)) 
    { 
     this->_file = fopen(path, mode); 
    } 

    ~File() 
    { 
     if (this->_refcount.unique()) 
     { 
      if (this->_file != NULL) 
      { 
       fclose(this->_file); 
      } 
     } 
    } 

    int write(void* buff, size_t size) 
    { 
     fwrite(buff, size, 1, this->_file); 
    } 

private: 
    FILE* _file; 
    std::tr1::shared_ptr<int> _refcount; 
}; 
+1

Безопасный в каком смысле? Безопасность в памяти? Нить безопасна? – kennytm

+0

@KennyTM Да, безопасный для памяти и потокобезопасный, а также с любых других точек зрения. (Я полагаю, что это не потокобезопасно, может быть, вы можете объяснить, как это можно исправить) –

+0

Я не сказал, что это не потокобезопасно;) Но я бы написал это как решение Джеймса, а не явное ref- счетчик. – kennytm

ответ

9

Рассмотрим вместо использования shared_ptr<FILE> с пользовательской Deleter:

struct fclose_deleter 
{ 
    void operator()(FILE* f) 
    { 
     if (f) 
     { 
      std::fclose(f); 
     } 
    } 
}; 

Тогда, ваш класс File намного проще (и исправителя):

class File 
{ 
public: 
    File(const char* path, const char* mode) 
     : _file(std::fopen(path, mode), fclose_deleter()) 
    { 
    } 

    int write(void const* buff, size_t size) 
    { 
     // You'll want to verify that _file.get() is valid, or you'll want to 
     // throw in the constructor if the call to 'std::fopen()' fails. 
     std::fwrite(buff, size, 1, _file.get()); 
    } 

private: 
    std::tr1::shared_ptr<FILE> _file; 
}; 
+0

класс может содержать любые данные (void *), файл является всего лишь примером –

+3

Этот метод применяется к любому объекту с подсчетом ссылок, который требует очистки. –

+1

Этот и другие интересные методы 'shared_ptr' можно найти здесь: http://www.boost.org/doc/libs/1_48_0/libs/smart_ptr/sp_techniques.html :) –

Смежные вопросы