Russian Qt Forum
Ноябрь 20, 2024, 02:55 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3 4 ... 6   Вниз
  Печать  
Автор Тема: Scoped  (Прочитано 37902 раз)
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #15 : Июль 14, 2013, 16:10 »

В boost'е тоже есть умные указатели)
Да там свой шаблончик будет на несколько строк.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #16 : Июль 14, 2013, 16:14 »

Ну вот, я так и знал Плачущий Полез делать template - и сразу надо еще что-то учить. Для текста выше не проходит
Код
template <class Ref, class Deleter>
struct CScopedRef {
..
Говорит, мол, Deleter ф-ция, а должен быть класс
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #17 : Июль 14, 2013, 16:18 »

Ну вот, я так и знал Плачущий Полез делать template - и сразу надо еще что-то учить. Для текста выше не проходит
Код
template <class Ref, class Deleter>
struct CScopedRef {
..
Говорит, мол, Deleter ф-ция, а должен быть класс

Ничего подобного) Можно и функцию вставить)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #18 : Июль 14, 2013, 16:28 »

Ничего подобного) Можно и функцию вставить)
Цитированием не злоупотребляйте если и так ясно о чем речь

Код
C++ (Qt)
template <typename TRef, typename TDeleter>
struct CScopedRef {
CScopedRef( TRef * ref ) : mRef(ref) {}
~CScopedRef( void ) { if (mRef) TDeleter(mRef); }
operator TRef * ( void ) { return mRef; }
 
void operator = ( TRef * ref )
{
if (mRef != ref) {
if (mRef) TDeleter(mRef);
mRef = ref;
}
}
 
private:
TRef * mRef;
CScopedRef( const CScopedRef & ) {}
void operator = ( const CScopedRef & ) {}
};
 
typedef CScopedRef <OpaqueRef, DestroyOpaqueRef> CScopedOpaqueRef;
 
На "инстанциации" вякает
Цитировать
error: type/value mismatch at argument 2 in template parameter list for 'template<class TRef, class TDeleter> struct CScopedRef'

error:   expected a type, got 'DestroyOpaqueRef'
« Последнее редактирование: Июль 14, 2013, 17:53 от Igors » Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #19 : Июль 14, 2013, 16:37 »

Хе хе) Конечно вякает)


Код
C++ (Qt)
template <typename TRef, typename TDeleter = default_deleter>
struct CScopedRef {
CScopedRef( TRef * ref, TDeleter deleter) : mRef(ref), mDeleter(deleter) {}
       CScopedRef( TRef * ref) : mRef(ref) {}
~CScopedRef( void ) { if (mRef) mDeleter(mRef); }
operator TRef * ( void ) { return mRef; }
 
void operator = ( TRef * ref )
{
if (mRef != ref) {
if (mRef) mDeleter(mRef);
mRef = ref;
}
}
 
private:
TRef * mRef;
       TDeleter mDeleter;
CScopedRef( CScopedRef & )
void operator = ( CScopedRef & )
};
 


Код
C++ (Qt)
typedef void (*FunctionType)(Ref *);
CScopedRef<Ref, FunctionType> ref(new Rew, DestroyOpaqueRef);
 
или ещё проще с decltype..
« Последнее редактирование: Июль 14, 2013, 16:44 от m_ax » Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #20 : Июль 14, 2013, 16:45 »

Тут два пути:
Три:
Код
C++ (Qt)
template<typename T, void (*destroyer)( T )>
struct CScopedRef {
{
public:
       ~CScopedRef() { destroyer( mRef ); }
 
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #21 : Июль 14, 2013, 16:48 »

Тут два пути:
Три:
Код
C++ (Qt)
template<typename T, void (*destroyer)( T )>
struct CScopedRef {
{
public:
       ~CScopedRef() { destroyer( mRef ); }
 


Да, так даже лучше)
Только igors туда уже ничего кроме void (*destroyer)( T ) не вставит)
Но, думаю, он не сильно расстроится)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #22 : Июль 14, 2013, 16:50 »

Тут два пути:
Три:
Код
C++ (Qt)
template<typename T, void (*destroyer)( T )>
struct CScopedRef {
{
public:
       ~CScopedRef() { destroyer( mRef ); }
 


Хотя подождите.. destroyer - это же тип..
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #23 : Июль 14, 2013, 16:51 »

И наверное лучше не завязываться на указателях, например может понадобиться такое:
Код
C++ (Qt)
typedef unsigned int HANDLE;
 
HANDLE create( ... );
destroy( HANDLE );
 

Пусть лучше пользователь шаблона задает точный тип:
Код
C++ (Qt)
CScoped<Data *, DestroyData> d1 = CreateData( ... );
CScoped<HANDLE, destroy> d2 = create( ... );
 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #24 : Июль 14, 2013, 16:52 »

Только igors туда уже ничего кроме void (*destroyer)( T ) не вставит)
Все он вставит. Улыбающийся
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #25 : Июль 14, 2013, 16:58 »


Хотя подождите.. destroyer - это же тип..

В смысле я к тому, что ему в любом случае придётся передавать указатель на функцию.. 
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #26 : Июль 14, 2013, 17:01 »

В смысле я к тому, что ему в любом случае придётся передавать указатель на функцию.. 
Тут, правда, будет затык, если какие то дестроеры имеют не такой прототип, например возвращают значение. Но тут уже Igors решать, по какому пути идти.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



Просмотр профиля
« Ответ #27 : Июль 14, 2013, 17:14 »


Хотя подождите.. destroyer - это же тип..

В смысле я к тому, что ему в любом случае придётся передавать указатель на функцию..  

Ааа.. Всё, дошло до меня) Я не о том подумал просто)
В таком варианте:
Код
C++ (Qt)
template<typename T, void (*destroyer)( T )>
struct CScopedRef {
{
public:
       ~CScopedRef() { destroyer( mRef ); }
 


указатель на функцию в конструкторе передавать уже ненужно) Всё верно)
Записан

Над водой луна двурога. Сяду выпью за Ван Гога. Хорошо, что кот не пьет, Он и так меня поймет..

Arch Linux Plasma 5
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #28 : Июль 14, 2013, 18:39 »

Да, так бычит, спасибо
Код
C++ (Qt)
template <typename TRef, void (*delFunc)(TRef *)>
struct CScopedRef {
CScopedRef( TRef * ref ) : mRef(ref) {}
~CScopedRef( void ) { if (mRef) delFunc(mRef); }
operator TRef * ( void ) { return mRef; }
 
void operator = ( TRef * ref )
{
if (mRef != ref) {
if (mRef) delFunc(mRef);
mRef = ref;
}
}
 
private:
TRef * mRef;
CScopedRef( const CScopedRef & ) {}
void operator = ( const CScopedRef & ) {}
};
 
typedef CScopedRef <OpaqueRef, DestroyOpaqueRef> CScopedOpaqueRef;
 
Но возникает маленькая неприяность.
Код
C++ (Qt)
OpaqueRef * src = CreateOpaqueRef();
CScopedOpaqueRef ref1(src);  // Ок
CScopedOpaqueRef ref2 = src;  // error
 
Цитировать
error: 'CScopedRef<TRef, delFunc>::CScopedRef(const CScopedRef<TRef, delFunc>&) [with TRef = OpaqueRef, void (* delFunc)(OpaqueRef*) = DestroyOpaqueRef]' is private
Да, он действительно private (я так и хотел), но чего она зовет конструктор копирования, если есть штатный?

Да. кстати, а с unique_ptr работает или m_ax меня просто на понт взял?  Улыбающийся Там вроде ситуевина та же, но у меня нет под рукой С++ 11
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #29 : Июль 15, 2013, 21:48 »


error: 'CScopedRef<TRef, delFunc>::CScopedRef(const CScopedRef<TRef, delFunc>&) [with TRef = OpaqueRef, void (* delFunc)(OpaqueRef*) = DestroyOpaqueRef]' is private

Да, он действительно private (я так и хотел), но чего она зовет конструктор копирования, если есть штатный?

Рассмотрим пример:

Код:
Some obj = 10;

На языке строгой статической типизации в правой части обязан быть объект такого же типа, как и в левой.

Поэтому, компилятор выполняет приведение типов, что есть суть запуск конструктора:

Код:
Some obj = 10;
эквивалент:
Код:
Some obj = Some(10);
Здесь сразу нужно заметить, что в правой части присутствует временный объект. И компилятор знает, что время жизни этого объекта - гарантированно до конца построения объекта в левой части.

Построение объекта в левой же части происходит по прототипу в правой части:
Код:
Some obj = Some(10);
эквивалент:
Код:
Some obj (  Some(10) );

Здесь нужно понимать: что временный объект в правой части первейший прентендент на оптимизацию RVO, то бишь в релизе компилятор запросто может выпилить все промежуточные конструкторы, изначально построив в левой части нужный объект.

Но в дебаге:

http://codepad.org/L0aneALk
Записан
Страниц: 1 [2] 3 4 ... 6   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.426 секунд. Запросов: 25.