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

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

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

Сообщений: 2095



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

И чтоб таких нежелательных сюрпризов не было (неявного преоброзования), умные люди используют explicit перед объявлением конструктора:

Код
C++ (Qt)
explicit CScopedRef( TRef * ref )
 
 
Записан

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

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

Сообщений: 2095



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

Цитировать
Да. кстати, а с unique_ptr работает или m_ax меня просто на понт взял? Там вроде ситуевина та же, но у меня нет под рукой С++ 11

Ну конечно на понт взял) А Вы повелись) Вообще не верьте ни тому что в boost'e пишут, ни в stl.. И документацию читать (да и вообще читать) тоже дело не благодарное - всё это для неизобретательных буквоедов и программистов средней руки и тех, кто совсем.. не очень)

Голова то не бездонная - получаем новые знания и опыт, а всё старое стирается (в корзину) без возможности восстановления(



   
Записан

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

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

Сообщений: 11445


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

Рассмотрим пример:
Код:
Some obj = 10;
Этот пример приводится много раз, но с др целью
Код
C++ (Qt)
Some obj;
obj = 10;   // вызывается оператор присваивания
..
Some obj2 = 10;   // вызывается конструктор (но не оператор присваивания)
 
Оказывается не просто конструктор, а конструктор копирования, а уж как там оптимизатор разрулит - то его дело. Да, проверил, все четко, спасибо

И чтоб таких нежелательных сюрпризов не было (неявного преоброзования), умные люди используют explicit перед объявлением конструктора:
Неумные его тоже используют Улыбающийся Но я совсем не хотел этого запрещать

Ну конечно на понт взял) А Вы повелись) Вообще не верьте ни тому что в boost'e пишут, ни в stl.. И документацию читать (да и вообще читать) тоже дело не благодарное - всё это для неизобретательных буквоедов и программистов средней руки и тех, кто совсем.. не очень)

Голова то не бездонная - получаем новые знания и опыт, а всё старое стирается (в корзину) без возможности восстановления(
Ну в общем правильно  Улыбающийся

А если std::unique_ptr работает - то объясните каким образом, не вижу каким образом удаляющая ф-ция оказывается описанной. Спасибо.
 
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



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

Цитировать
А если std::unique_ptr работает - то объясните каким образом, не вижу каким образом удаляющая ф-ция оказывается описанной. Спасибо.

Да вот так:

Код
C++ (Qt)
#include <iostream>
#include <memory>
 
void deleter(int *) {
   std::cout << "user deleter" << std::endl;
}
 
typedef void (*func_t)(int *);
 
int main()
{
 
   std::unique_ptr<int, func_t> p(new int(10), deleter);
 
   return 0;
}
 
 

Цитировать
Неумные его тоже используют. Но я совсем не хотел этого запрещать
И плохо, что не хотели..
В реализации умных указателей, такое неявное преобразование типов запрещено..  И не просто так, между прочим)
« Последнее редактирование: Июль 16, 2013, 13:35 от m_ax » Записан

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

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

Сообщений: 11445


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

Да вот так:
Ну так и я могу. Я имел ввиду
Код
C++ (Qt)
template <class Ref, class Deleter>
void TestProc( Ref * ref, Deleter del )
{
del(ref);
}
 
void MyDel ( int * a ) { printf("%d\n", *a); }
int  MyDel2 ( int * a ) { return *a + 1; }
 
int main( void )
{
int a = 5;
TestProc(&a, MyDel);
TestProc(&a, MyDel2);
 
return 0;
}
Здесь я могу подсовывать все что угодно, абы було (). А вот с template-классом так не выходит  Плачущий 
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



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

Цитировать
Здесь я могу подсовывать все что угодно, абы було (). А вот с template-классом так не выходит

И что? Чем это принципиально выигрышней, чем вариант с unique_ptr?
Вы не знаете какой делитер вставить на момент создания  unique_ptr?
Это ерунда какая то.., либо Вы сами не знаете чего хотите..
Записан

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

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

Сообщений: 4350



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

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

Сообщений: 2095



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

Это ерунда какая то.., либо Вы сами не знаете чего хотите..
Как я понял, Igors интересно, как достигается возможность указывать и функтор и функцию. Подмигивающий


А я вот понять всё никак не могу:
Цитировать
Здесь я могу подсовывать все что угодно, абы було (). А вот с template-классом так не выходит

и далее в примере:
Код
C++ (Qt)
       TestProc(&a, MyDel);
TestProc(&a, MyDel2);
 

Делитор по смыслу своему и предназначению, назначается объекту один раз и срабатывает тоже однажды, в самом конце. Менять его между началом и концом жизни объекта - это и есть ерунда.. Поэтому он и назначается объекту при его создании (объекта) один раз.
Если на момент создания объекта, неизвестно поведение делитора для него, то здесь уже чего то с логикой.. не того.. 

Или быть может я чего то не понимаю, чего хотел сказать igors..  Непонимающий
Записан

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

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

Сообщений: 4350



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

В unique_ptr в качестве дестроера можно указать и объект-функтор и функцию. Как я понимаю Igors интересно как это реализуется.
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



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

В unique_ptr в качестве дестроера можно указать и объект-функтор и функцию. Как я понимаю Igors интересно как это реализуется.

И даже использовать в качестве делитора метод класса.)
Записан

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

Arch Linux Plasma 5
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


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

Оказывается не просто конструктор, а конструктор копирования, а уж как там оптимизатор разрулит - то его дело. Да, проверил, все четко, спасибо

Вы не совсем уловили суть.

Суть заключается вот в этом вот вашем: "оказывается не просто конструктор, а конструктор копирования".

Дело в том, что из-за всякого рода оптимизаций, компилятор может использовать move-semantic, и выпилить копирующий конструктор. Тогда его явление станет не наблюдаемым. Это нужно учитывать.

По стандарту, вы имеете полное право рассчитывать только на то, что:
Код:
Some obj = 10; //гарантированно запустится конструктор с параметром

И я вам очень настоятельно не рекомендую рассчитывать на то, что запуск копирующего конструктора будет наблюдаем.

Более того, в вижал студии вы вообще не получите наблюдаемого конструктора копии. даже в дебаге:
Код:
struct Test
{
   Test(const Test& src) { cout<<"copy\n"; }
   Test(int src) { cout<<"ctor with param\n"; }
};

int main()
{
   Test t =10;
   //вывод в консоль: ctor with param
}

Во-первых, студия пренебрегает стандартом там, где стандарт начинает противоречить здравому смыслу (ну действительно: накой хрен тут упал этот конструктор копий, если все равно все сводится к построению бинарно-эквивалентному конструктором с параметром? )

А во-вторых, и вот это уже более важный аспект разработки:

Код:
//debug:gcc
struct Test
{
   Test(int src) { cout<<"ctor with param\n"; }
private:
   Test(const Test& src) { cout<<"copy\n"; }
};

int main()
{
   Test t =10;
   //Line 8: error: 'Test::Test(const Test&)' is private
}


Код:
//debug:mvs
struct Test
{
   Test(const Test& src) { cout<<"copy\n"; }
private:
   Test(int src) { cout<<"ctor with param\n"; } //<--- запрещен
};

int main()
{
   Test t =10;

   //успешная компиляция
   //вывод в консоль: ctor with param
}

Можно запросто подорваться на грабильках различий в поведении разных компиляторов.

Поэтому, я вам очень настоятельно рекомендую исходить из того, что запуск копирующего конструктора "как бы соптимизирован" и не рассчитывать на его запуски при создании объекта с семантикой присвоения.
« Последнее редактирование: Июль 16, 2013, 21:33 от _Bers » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

В unique_ptr в качестве дестроера можно указать и объект-функтор и функцию. Как я понимаю Igors интересно как это реализуется.
Это понятно, но совсем не так удобно как с tempate ф-цией
Код:
    std::unique_ptr<int, func_t> p(new int(10), deleter);
Ну что это за длинная сопля? Надо использовать еще один typedef. Если ф-ция удаления хоть как-то отличается - еще городить typedef

Похожие проблемы с auto_ptr. Вроде "все по уму", но get() неприятно нагружает исходник, а в отладчике пока доберешься "до тела" Плачущий  В итоге выигрыш не так уж велик, нередко проще поставить пару if'ов ограничившись "просто указателем"
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


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

По стандарту, вы имеете полное право рассчитывать только на то, что:
Цитировать
Some obj = 10; //гарантированно запустится конструктор с параметром
Да, проверил (gcc)
Код
C++ (Qt)
#include <stdio.h>
 
struct CTest {
CTest( int a ) : mA(a)
{
printf("def ctor\n");
}
 
CTest( const CTest & src )
{
printf("copy ctor\n");
mA = src.mA;
}
 
int mA;  
};
 
int main( void )
{
CTest test = 5;
return 0;
}
 
Конструктор копирования НЕ вызывается, однако он не может быть private. Какая-то логика в этом есть, ну ладно, придется ограничиться явным вызовом крнструктора

И я вам очень настоятельно не рекомендую ..
...
Поэтому, я вам очень настоятельно рекомендую ...
Вы даете действительно хорошие, содержательные ответы, но без менторского "рекомендую" они были бы еще лучше  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



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

Ну что это за длинная сопля? Надо использовать еще один typedef. Если ф-ция удаления хоть как-то отличается - еще городить typedef
Какой еще один?

Похожие проблемы с auto_ptr. Вроде "все по уму", но get() неприятно нагружает исходник
Какой get? Зачем get? Если есть ->
Но наверное хочется страдать... Улыбающийся

 В итоге выигрыш не так уж велик, нередко проще поставить пару if'ов ограничившись "просто указателем"
Конечно, поэтому вы и начали эту тему. Улыбающийся
Записан
m_ax
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2095



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

Ну что это за длинная сопля? Надо использовать еще один typedef. Если ф-ция удаления хоть как-то отличается - еще городить typedef
Какой еще один?

Видимо, на тот случай, если делитор будет что-нибудь возвращать) Правда я не понимаю для чего, а главное как igors будет использовать это возвращаемое значение  Непонимающий


Записан

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

Arch Linux Plasma 5
Страниц: 1 2 [3] 4 5 6   Вверх
  Печать  
 
Перейти в:  


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