| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Конструктор копирования в абстрактном классе |
| Автор: BSOD 14.12.2008, 21:07 |
| Есть такая проблема: Есть абстракстный интерфейс стека (Stack), в нем есть операции Top, Delete, Insert, ForEach и (!) operator= ну, и еще нам нужен оператор копирования Стек может быть реализован как угодно в классе наследнике. Возникает проблема реализовать конструктор копирования... В конструкторе копирования я использую виртуальную функцию clone, которую потом перегружаю в каждой реализации, но, в clone-то передается ссылка на Stack (наш интерфейс), чез который не особо-то и можно скопировать... Вот сейчас думаю, как его реализовать, были такие идеи: использовать ForEach и Insert... отлично, но мы не можем в ForEach передать функцию-член класса :( и два варианта: 1. реализовать функцию at(int) для доступа к i-тому элементу стека, но 1. Стек может быть реализован через список, а тогда это плохо 2. Никакого at по условию нет в абстрактном классе 2. написать итератор... но это будет еще хуже впихиваться в условия задачи (пишу не себе ;))... и походу этого делать не буду Вот. Что собсно можно сделать еще? |
| Автор: Lazin 14.12.2008, 21:13 |
использовать статический полиморфизм, а не динамический было-бы логичней в данном случае |
| Автор: BSOD 14.12.2008, 21:26 |
| Нееее, хотя бы потому, что это не подойдет под условие задачи еще больше, чем любой другой изврат... :( |
| Автор: Lazin 14.12.2008, 21:40 |
| это не изврат, если ты хочешь реализзовать конструктор копирования, значит тебе нужна семантика значений, тоесть абстрактный базовый класс здесь совершенно не у дел. конструктор копирования нельзя сделать виртуальным, соответственно в абстрактном базовом классе ему нет места, так как у него по определению нет состояния. |
| Автор: BSOD 14.12.2008, 21:43 |
| Почему же, если бы в базом класе были функции для доступа не только к первому элементу, но и ко всем, то все бы реализовывалось, т.е. скорее всего что-то вводить придется, вопрос - что... |
| Автор: Alek86 14.12.2008, 21:45 | ||
| можно использовать паттерн Посетитель типа такого выйдет есть StackParent и дети: Stack1, Stack2
Добавлено @ 21:46 то же и с copy constructor хотя не совсем так - в моем случае интерфейс StackParent зависит от наследников дальше думать лень, но, вроде, Посетитель и эту проблему решает |
| Автор: BSOD 14.12.2008, 21:48 | ||
Тогда мы должны знать всех потомков... |
| Автор: Alek86 14.12.2008, 21:50 |
| точно, надо выделить интерфейс Посетителя, который будет за тех потомков отвечать подробнее - в инете, по запросу "паттерн Посетитель" |
| Автор: Alek86 14.12.2008, 22:09 |
| mes, если есть 2 потомка - stack1 и stack2, то между ними - 4 варианта копирования если 3 потомка - 6 вариантов и так далее а вирт функция - только одна |
| Автор: Lazin 14.12.2008, 22:12 | ||||
| вот поэтому в таких случаях не используют конструктор копирования. если твой стек поддерживает итераторы, то можно вместо метода clone, добавить методы begin, end и assign Добавлено через 1 минуту и 50 секунд
или
|
| Автор: mes 14.12.2008, 22:16 | ||||
то есть надо чтоб
тогда Clone, то тут не при чем ! |
| Автор: Alek86 14.12.2008, 22:16 |
| с чего это стеку вдруг поддерживать итераторы? можно, конечно, с пом pop, top, push скопировать, но это ж будет довольно неэкономично Добавлено через 23 секунды mes, да, к примеру |
| Автор: mes 14.12.2008, 22:23 | ||
если эту задача решать эффективно через полиморфизм базового класса, то без визитера не обойтись. В другом случае каждый наследник, должен уметь себя создавать имея ссылку на базовый интерфейс. Добавлено @ 22:25
а функтор можем передавать ? |
| Автор: BSOD 14.12.2008, 22:31 | ||||
На самом деле это всего-лишь в 3 раза "неэкономичнее", чем просто копирование ;)... и этот вариант я тож рассматривал (на крайняк Да, я понимаю, что это совсем жуткий изврат, но всеравно, ведь это будет работать (1), мы не будем менять ничего в абстрактном классе (2) и это даже не будет особо тормозить (!) сорри, что я тут сам с собой нафлудил немного, эмоции Добавлено через 1 минуту и 21 секунду
Эммм, а кстати да, как вариант... но всеравно, придется немного, да подправить базовый класс.. |
| Автор: mes 14.12.2008, 22:38 | ||
a foreach что принимает ?? |
| Автор: J0ker 14.12.2008, 23:02 | ||
|
| Автор: BSOD 14.12.2008, 23:08 | ||||||
а в потомке уже
а так нельзя, получится, что нет реализации чисто виртуальной функции в классе потомке ;) Это как бы было первое, что все пробовали, после чего эта проблема и обнаружилась ;) Добавлено через 34 секунды
Указатель на функцию |
| Автор: J0ker 14.12.2008, 23:27 | ||
можно перегруженная переопределенная функция может возвращать указатель или ссылку на потомков/предков возвращаемого оригинала |
| Автор: mes 14.12.2008, 23:33 | ||||||
BSOD, мне кажется, имел ввиду что при такой конструкции не получится сделать следующее :
Добавлено @ 23:35 думаю подойдет такой вот насбросок:
|
| Автор: J0ker 14.12.2008, 23:44 | ||
такое и не должно получаться, если D1 и D2 не являются ковариантами для таких присвоений надо делать либо оператор преобразования типов либо специальный оператор= Добавлено через 2 минуты и 19 секунд функцию копирования лучше делать внешней и темплетной - как и сделано в STL непонятно, зачем изобретать велосипед |
| Автор: mes 15.12.2008, 00:09 | ||||||
ну да я сильно упростил, так будет точнее
согласен...но в классе я оставил ee специально для демонстрации, мне показалось так для тс будет яснее подходит ли ему такой способ или нет, а сама функция фактически и не нужна (только как оболочка), всю реализацию несет на себе функтор . как понял для сессии. |
| Автор: BSOD 15.12.2008, 00:16 | ||||||||||
Я не про то, прост мы же получается не перегрузим функцию из родителя а введем новую. А т.к. в родителе наша функция чисто виртуальная, то компилер будет ругаться, что мы не ее не перегрузили в потомке.
Ну вот это я думаю прокатит, но я вроде бы как-то ужн реализовал, сейчас буду смотреть, что получилось Добавлено через 6 минут и 13 секунд
ну на самом деле наверное нужно было
;)
Что-то типа того |
| Автор: mes 15.12.2008, 00:24 | ||
А Вы попробуйте и будете сильно удивлены Только такая технология позволяет только клонирование, но не копирование объекта от потомка к потомку другого типа. |
| Автор: J0ker 15.12.2008, 00:25 | ||
нет, мы именно перегрузим переопределим не будет |
| Автор: mes 15.12.2008, 00:28 |
| ... |
| Автор: J0ker 15.12.2008, 00:30 |
| вы меня запутали млин не перегрузка конечно, а переопределение |
| Автор: BSOD 15.12.2008, 20:34 | ||
Сорри, немного не досмотрел, так действительно должно работать Сделал почти так, только Клон ничего не возвращает, а в него передается ссылка на другой стек, куда он себя и копирует Всем спасибо, вопрос вроде как исчерпан |