Название: Копирование структур с укзателями Отправлено: Igors от Июль 12, 2016, 10:23 Добрый день
Есть структура Код Где реально член mData = указателю на одного из наследников абстрактного класса AbstractClass. Как удобно (или лучше всего) скопировать экземпляр CData? Спасибо Название: Re: Копирование структур с укзателями Отправлено: Racheengel от Июль 12, 2016, 11:32 Зависит от того, нужно ли шарить mData между структурами или надо создавать каждый раз копию объекта.
Если последнее, то AbstractClass должен иметь что-то типа virtual AbstractClass* clone(), и все его наследники - соответствующие имплементации, чтобы гарантированно создавать копию правильного потомка. Название: Re: Копирование структур с укзателями Отправлено: _Bers от Июль 12, 2016, 22:26 Как удобно (или лучше всего) скопировать экземпляр CData? конструктором копии по умолчанию, очевидно жеж. Название: Re: Копирование структур с укзателями Отправлено: Igors от Июль 13, 2016, 06:32 AbstractClass должен иметь что-то типа virtual AbstractClass* clone(), Так сейчас и сделано, только Clone с большой буквы :)конструктором копии по умолчанию, очевидно жеж. Очевидно-то оно очевидно, только хлопотливо - virtual заводи, конструктор копирования и оператор присваивания перекрывай. Думал может какой-то "вумный указатель" позволит достичь того же более компактно - но видимо нет.Название: Re: Копирование структур с укзателями Отправлено: _Bers от Июль 13, 2016, 07:51 Очевидно-то оно очевидно, только хлопотливо - virtual заводи, конструктор копирования и оператор присваивания перекрывай. Думал может какой-то "вумный указатель" позволит достичь того же более компактно - но видимо нет. вы не поняли - конструктор копии по умолчанию. не нужны никакие пользовательские конструкторы копии, не нужны никакие дополнительные виртуальные функции. после копирования, mData обоих экземпляров будет хранить одно и тоже значение. если вам нужно клонировать наследника, то это нужно сообщать в изначальной постановке задачи. в этом случае, самый годный вариант - использовать смарт-поинтер, вместо сырого указателя. то есть, вместо: Код: AbstractClass * mData; использовать: Код: wrapper<AbstractClass> mData; тогда не придется реализовывать виртуальный clone в каждом возможном наследнике. и вручную следить за временем жизни ресурса. стандартные смарт-поинтеры из коробки такое не умеют. но вооружившись паттерном type erasure, вы легко сможете завелосипедить необходимую вам функциональность. здесь самое главное - определиться с принципов владения ресурсом смарта: он должен вести себя подобно unique_ptr, или shared_ptr ? или же он, как приличный, уважающий себя враппер, должен олицетворять собой "объект по значению" ? классический дизайн подобного рода механизмов: Код: { // example пример из стандартной библиотеки: http://rextester.com/MSFNN7783 Код: #include <iostream> к сожалению, стандартные смарт-поинтеры не поддерживают clone из коробки. поэтому, приходится велосипедить своё. Название: Re: Копирование структур с укзателями Отправлено: Igors от Июль 13, 2016, 10:03 если вам нужно клонировать наследника, Если нужно шарить - то просто шаред пойнтер, и все дела. Думаю это и так всем ясно. Разумеется речь о клонировании.то это нужно сообщать в изначальной постановке задачи. здесь самое главное - определиться с принципов владения ресурсом смарта: С "олицетворять" с Вашей помощью вроде разобрался. Вот сочинил примерон должен вести себя подобно unique_ptr, или shared_ptr ? или же он, как приличный, уважающий себя враппер, должен олицетворять собой "объект по значению" ? Код Правильно ли я понял? Спасибо Название: Re: Копирование структур с укзателями Отправлено: Igors от Июль 13, 2016, 11:25 Нет, не дотягивается он до не-виртуального деструктора. Это конечно можно пережить но
Код (классика советского кино) Код Edit: почистил и исправил ошибку Название: Re: Копирование структур с укзателями Отправлено: _Bers от Июль 13, 2016, 12:02 классика советского кино говнокод лютый, но идею вы вроде уловили. Название: Re: Копирование структур с укзателями Отправлено: Igors от Июль 13, 2016, 15:56 // при помощи паттерна type erasure К чему сводится это "запоминание"? Не явно же его запоминать как число или строку. Я понял так// враппер "запомнил" тип ресурса, который он захватил - внутри враппера объявляется базовый класс с виртуальными методами, от него наследуется темплейт класс - в момент когда известен/приходит реальный тип (напр set<T2> выше) создается экземпляр реального типа и указатель на него сохраняется в враппере как указатель на базовый класс. Он и используется (через виртуалы) для вызова нужных методов, реальный тип по-прежнему врапперу неизвестен, но он может рулить. Верно? говнокод лютый, но идею вы вроде уловили. Там неверно было, исправил. По поводу говнокода - интересная тема. Возможно через месяц-другой я сам не пойму текст что сейчас написал. Куча каких-то мелких классов, хелперов, сходу хрен поймешь что они делают. Ну а как иначе? Я не могу их не писать связавшись с этой гребаной "магией". В конце-концов исходники стандартного std никак не более понятны. Нет, конечно на этапе использования все хорошо, когда пристроился и знаешь как юзать. Но все-таки наверное незатейливый вариант с виртуальным Clone предпочтительнее (хотя объективно слабее). Что Вы об этом думаете?Название: Re: Копирование структур с укзателями Отправлено: _Bers от Июль 13, 2016, 16:39 Верно? ага.Там неверно было, исправил. По поводу говнокода - интересная тема. Возможно через месяц-другой я сам не пойму текст что сейчас написал. Куча каких-то мелких классов, хелперов, сходу хрен поймешь что они делают. Ну а как иначе? 1. православный хелпер: не аллоцируется в куче. это медленно, и в этом нет ни какой нужды. он не должен иметь собственных детей. 2. наследника тоже без нужды не нужно аллоцировать в куче. обычно выделяют стековую память, и алллоцируют в куче, только если наследник совсем туда не влезает. 3. локальные классы сильно усложняют понимание. можно вынести в спейс details. код сразу упроститься. 4. не нужно использовать в плюсовом коде сишные подходы. 5. у вас там были какие то баги. не знаю, что вы потом поправили, я сильно не вникал. лично я когда что-то подобное велосипедировал, написал кучку тестов, для контроля за утечками памяти, поведением при копировании, клонировании, разыменовывании, и тп. поскольку использовал стек, а не дин. аллокации, то особое внимание уделил выравниванию данных, и стрикт-алиасингу. ну и потом просто наслаждался жизнью. сделать отдельный тестовый проект - это важно. потому что подобные механизмы - механизмы общего назначения. как в стандартной библиотеке, или как в бусте. они имеют замороченную реализацию, но не должны оказывать нагрузку на сопровождение бизнес проекта. нужно один раз сделать по уму. удостовериться, что все работает хорошо. что бы потом использовать в бизнес-приложениях, и можно было закладываться на их надежность и работоспособность. Название: Re: Копирование структур с укзателями Отправлено: Igors от Июль 13, 2016, 18:55 Вот переделал по образцу QSharedPtr, пусть клиент заряжает new - проще. Попинайте
Код Edit: нашел еще ошибку - исправил Название: Re: Копирование структур с укзателями Отправлено: _Bers от Июль 14, 2016, 11:56 Вот переделал по образцу QSharedPtr, пусть клиент заряжает new - проще. Попинайте в код не вникал, но что-то там у вас не срослось: http://rextester.com/YEPJT26606 Цитировать Error(s): Process exit code is not 0: -1073740940 Consruct Base Consruct Base Consruct Derived Test1 ptr1 = Base(1) ptr2 = Derived(2,3) ptr1 = Derived(2,3) ptr2 = Derived(2,3) зы: вот я вам выше предложил написать годный тестовый проект (например, с использованием google mock) и провести полноценное тестирование. судя по всему, вы решили пренебречь этим. понимаете, через полгода какой то кейс сломает ваш класс, и программист бизнес-логики будет репу чесать, пытаясь понять вот этот "технологичный" код. конечно, с позиции человека, который уже специалист по части шаблоно-магии, и тп, тут никаких особых сложностей нет. вам может показаться, что реализация не такая уж и сложная, но в реальности для очень многих ребят подобный код - реально покажется сложным и замороченным. поэтому, вы окажете услугу всем своим коллегам, если тщательно протестируете свой механизм, и избавите их от необходимости вникать в детали его реализации. Название: Re: Копирование структур с укзателями Отправлено: Igors от Июль 14, 2016, 12:35 вот я вам выше предложил написать годный тестовый проект А давайте. Вот я зарегистрипрвался и поместил туда свой код http://rextester.com/LWYA1042 (http://rextester.com/LWYA1042) Что мне делать дальше на пути к "полноценному тестированию"? (просто никогда не пользовался google mock). Спасибо (например, с использованием google mock) Название: Re: Копирование структур с укзателями Отправлено: _Bers от Июль 14, 2016, 23:19 вот я вам выше предложил написать годный тестовый проект А давайте. Вот я зарегистрипрвался и поместил туда свой код http://rextester.com/LWYA1042 (http://rextester.com/LWYA1042) Что мне делать дальше на пути к "полноценному тестированию"? (просто никогда не пользовался google mock). Спасибо (например, с использованием google mock) так я вам помочь не могу. для тестирования я использую фреймворк google test но его нет на онлайн компиляторе впрочем, если вас это заинтересовало, то вот пример использования: https://www.youtube.com/watch?v=6pp8S56sS2Y&feature=youtu.be хотя я конечно немножко по другому делаю. но в целом для старта неплохой мануал. Название: Re: Копирование структур с укзателями Отправлено: Igors от Июль 15, 2016, 10:38 Ой нет, это сложно. И так почти 2 дня провозился с "интересной фишкой", а работа стоит. Немного расширил свое понимание template - ну и хорошо. Спасибо за помощь.
Название: Re: Копирование структур с укзателями Отправлено: Авварон от Июль 15, 2016, 13:18 Ой нет, это сложно. И так почти 2 дня провозился с "интересной фишкой", а работа стоит. А потом эти люди на учат как правильно писать код, лол. |