Обоснование защищенного деструктора

Я заметил, что многие классы Poco имеют защищенный деструктор. Это делает их более раздражающими для кодирования. Например, вот часть моего кода:

struct W2: Poco::Util::WinRegistryConfiguration
{
    typedef Poco::Util::WinRegistryConfiguration inherited;
    using inherited::inherited;
};

std::string get_documents_folder()
{
    W2 regc { "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"  };
    return regc.getString("Personal", "");
}

Конечно, было бы намного проще, если бы я мог покончить с W2 и просто сделать regc типом WinRegistryConfiguration. Но это невозможно из-за защищенного деструктора.

Я понимаю, что вместо этого можно использовать Poco::AutoPtr, но тогда ресурсы тратятся впустую, выполняя динамическое выделение с помощью new, тогда как автоматическое выделение должно работать нормально.

У меня вопрос: в чем причина этого и не упускаю ли я что-нибудь?


person M.M    schedule 20.07.2015    source источник


Ответы (2)


Как уже было сказано, Poco::RefCountedObject имеет защищенный деструктор, поэтому все классы, унаследованные от него, не могут быть созданы в стеке. Причина в том, что они удаляют себя, когда счетчик ссылок достигает нуля, поэтому их создание в стеке вызовет неопределенное поведение — они в первую очередь предназначены для использования с Poco:: AutoPtr, но это не обязательно — вы также можете вручную подсчитать количество ссылок, используя дубликат() и выпуск().

Глядя на свой код, вы, вероятно, ищете WinRegistryKey, который можно использовать следующим образом:

std::string get_documents_folder()
{
  Poco::Util::WinRegistryKey regKey("HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
  return regKey.getString("Personal", "");
}
person Alex    schedule 28.07.2015

Причина в том, что WinRegistryConfiguration использует счетчик ссылок (наследуется от Poco::RefCountedObject). Защищенный деструктор предназначен для предотвращения создания клиентами класса в стеке или прямого удаления объекта. Вместо этого вы должны создать экземпляр класса с помощью new и управлять временем жизни с помощью методов RefCountedObject.

Я не знаком с Poco, но также должен быть класс интеллектуальных указателей, который управляет объектами с подсчетом ссылок, автоматически вызывая методы RefCountedObject.

person user1610015    schedule 20.07.2015