Сообщение Re[3]: Как получить тип по указателю на него? от 26.06.2018 20:28
Изменено 27.06.2018 8:24 Кодт
Re[3]: Как получить тип по указателю на него?
Здравствуйте, LazyKarlson, Вы писали:
LK>Тоже работает, да, хотя введение дополнительной структуры.. ну.. шашечки. Но я не об этом. Не могу понять, почему вот так
LK>
LK>не работает? Я всего лишь убрал переопределение типа...
Потому что так задумано. Чтобы можно было хранить в unique_ptr произвольные указатели.
https://en.cppreference.com/w/cpp/memory/unique_ptr
unique_ptr<T,Deleter> берёт тип "указатель" из Deleter::pointer, либо, если это не указано, считает указателем тип T*.
Правда, совсем уж произвольные типы там хранить не получится, (например, int с сигнальным значением -1 — всякие позиксовые дескрипторы).
А только NullablePointer.
Кстати говоря, HKEY тоже формально нельзя хранить: у него сигнальное значение INVALID_HANDLE_VALUE = (HKEY)(intptr_t)(-1).
Но практика показывает, что в WinAPI не встречаются хэндлы со значением 0. То есть, мы не получим здесь утечку ресурсов из-за того, что unique_ptr((HKEY)0) откажется вызывать RegCloseKey.
Кстати говоря!
Если уж писать на плюсах под WinAPI, то было бы очень естественно взять библиотеку ATL, в которой есть умные хэндлы. Конкретно, здесь — CRegKey.
Ну или если ATL тащить не хочется, то скопипастить своё — это же дело пары минут. Там не рокет саенс, всего-то — написать кучу стандартных методов.
LK>Тоже работает, да, хотя введение дополнительной структуры.. ну.. шашечки. Но я не об этом. Не могу понять, почему вот так
LK>
LK>struct RegKeyDeleter
LK>{
LK> //using pointer = HKEY;
LK> void operator()(HKEY p) const
LK> {
LK> RegCloseKey(p);
LK> }
LK>};
LK>using unique_reg_key = std::unique_ptr<HKEY, RegKeyDeleter>;
LK>
LK>не работает? Я всего лишь убрал переопределение типа...
Потому что так задумано. Чтобы можно было хранить в unique_ptr произвольные указатели.
https://en.cppreference.com/w/cpp/memory/unique_ptr
unique_ptr<T,Deleter> берёт тип "указатель" из Deleter::pointer, либо, если это не указано, считает указателем тип T*.
Правда, совсем уж произвольные типы там хранить не получится, (например, int с сигнальным значением -1 — всякие позиксовые дескрипторы).
А только NullablePointer.
Кстати говоря, HKEY тоже формально нельзя хранить: у него сигнальное значение INVALID_HANDLE_VALUE = (HKEY)(intptr_t)(-1).
Но практика показывает, что в WinAPI не встречаются хэндлы со значением 0. То есть, мы не получим здесь утечку ресурсов из-за того, что unique_ptr((HKEY)0) откажется вызывать RegCloseKey.
Кстати говоря!
Если уж писать на плюсах под WinAPI, то было бы очень естественно взять библиотеку ATL, в которой есть умные хэндлы. Конкретно, здесь — CRegKey.
Ну или если ATL тащить не хочется, то скопипастить своё — это же дело пары минут. Там не рокет саенс, всего-то — написать кучу стандартных методов.
class RegKey {
public:
RegKey() {}
explicit RegKey(HKEY h) : h_(h) {}
RegKey(RegKey&& r) { r.swap(*this); }
~RegKey() { if (h_ != INVALID_HANDLE_VALUE) ::RegCloseKey(h_); }
RegKey& operator = (HKEY h) { return *this = CRegKey(h); }
RegKey& operator = (RegKey&& r) { r.swap(*this); return *this; }
void swap(RegKey& r) { swap(h_, r.h_); }
HKEY detach() { HKEY h = h_; h_ = INVALID_HANDLE_VALUE; return h; }
HKEY get() const { return h_; }
// operator * и -> смысла не имеют, т.к. HKEY не разыменуемый
operator bool() const { return h_ != INVALID_HANDLE_VALUE; }
private:
HKEY h_ = INVALID_HANDLE_VALUE;
};
Re[3]: Как получить тип по указателю на него?
Здравствуйте, LazyKarlson, Вы писали:
LK>Тоже работает, да, хотя введение дополнительной структуры.. ну.. шашечки. Но я не об этом. Не могу понять, почему вот так
LK>
LK>не работает? Я всего лишь убрал переопределение типа...
Потому что так задумано. Чтобы можно было хранить в unique_ptr произвольные указатели.
https://en.cppreference.com/w/cpp/memory/unique_ptr
unique_ptr<T,Deleter> берёт тип "указатель" из Deleter::pointer, либо, если это не указано, считает указателем тип T*.
Правда, совсем уж произвольные типы там хранить не получится, (например, int с сигнальным значением -1 — всякие позиксовые дескрипторы).
А только NullablePointer.
Кстати говоря, HKEY тоже формально нельзя хранить: у него сигнальное значение INVALID_HANDLE_VALUE = (HKEY)(intptr_t)(-1).
Но практика показывает, что в WinAPI не встречаются хэндлы со значением 0. То есть, мы не получим здесь утечку ресурсов из-за того, что unique_ptr((HKEY)0) откажется вызывать RegCloseKey.
Кстати говоря!
Если уж писать на плюсах под WinAPI, то было бы очень естественно взять библиотеку ATL, в которой есть умные хэндлы. Конкретно, здесь — CRegKey.
Ну или если ATL тащить не хочется, то скопипастить своё — это же дело пары минут. Там не рокет саенс, всего-то — написать кучу стандартных методов.
LK>Тоже работает, да, хотя введение дополнительной структуры.. ну.. шашечки. Но я не об этом. Не могу понять, почему вот так
LK>
LK>struct RegKeyDeleter
LK>{
LK> //using pointer = HKEY;
LK> void operator()(HKEY p) const
LK> {
LK> RegCloseKey(p);
LK> }
LK>};
LK>using unique_reg_key = std::unique_ptr<HKEY, RegKeyDeleter>;
LK>
LK>не работает? Я всего лишь убрал переопределение типа...
Потому что так задумано. Чтобы можно было хранить в unique_ptr произвольные указатели.
https://en.cppreference.com/w/cpp/memory/unique_ptr
unique_ptr<T,Deleter> берёт тип "указатель" из Deleter::pointer, либо, если это не указано, считает указателем тип T*.
Правда, совсем уж произвольные типы там хранить не получится, (например, int с сигнальным значением -1 — всякие позиксовые дескрипторы).
А только NullablePointer.
Кстати говоря, HKEY тоже формально нельзя хранить: у него сигнальное значение INVALID_HANDLE_VALUE = (HKEY)(intptr_t)(-1).
Но практика показывает, что в WinAPI не встречаются хэндлы со значением 0. То есть, мы не получим здесь утечку ресурсов из-за того, что unique_ptr((HKEY)0) откажется вызывать RegCloseKey.
Кстати говоря!
Если уж писать на плюсах под WinAPI, то было бы очень естественно взять библиотеку ATL, в которой есть умные хэндлы. Конкретно, здесь — CRegKey.
Ну или если ATL тащить не хочется, то скопипастить своё — это же дело пары минут. Там не рокет саенс, всего-то — написать кучу стандартных методов.
class RegKey {
public:
RegKey() {}
explicit RegKey(HKEY h) : h_(h) {}
RegKey(RegKey&& r) { r.swap(*this); }
~RegKey() { if (h_ != INVALID_HANDLE_VALUE) ::RegCloseKey(h_); }
RegKey& operator = (HKEY h) { return *this = RegKey(h); }
RegKey& operator = (RegKey&& r) { r.swap(*this); return *this; }
void swap(RegKey& r) { swap(h_, r.h_); }
HKEY detach() { HKEY h = h_; h_ = INVALID_HANDLE_VALUE; return h; }
HKEY get() const { return h_; }
// operator * и -> смысла не имеют, т.к. HKEY не разыменуемый
operator bool() const { return h_ != INVALID_HANDLE_VALUE; }
private:
HKEY h_ = INVALID_HANDLE_VALUE;
};