Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Конструктор копирования в абстрактном классе, стек 
V
    Опции темы
BSOD
Дата 14.12.2008, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 405
Регистрация: 1.11.2004
Где: Гомель

Репутация: нет
Всего: 3



Есть такая проблема:

Есть абстракстный интерфейс стека (Stack), в нем есть операции Top, Delete, Insert, ForEach и (!) operator= ну, и еще нам нужен оператор копирования
Стек может быть реализован как угодно в классе наследнике.
Возникает проблема реализовать конструктор копирования... В конструкторе копирования я использую виртуальную функцию clone, которую потом перегружаю в каждой реализации, но, в clone-то передается ссылка на Stack (наш интерфейс), чез который не особо-то и можно скопировать...
Вот сейчас думаю, как его реализовать, были такие идеи:
использовать ForEach и Insert... отлично, но мы не можем в ForEach передать функцию-член класса :(
и два варианта:
1. реализовать функцию at(int) для доступа к i-тому элементу стека, но 1. Стек может быть реализован через список, а тогда это плохо 2. Никакого at по условию нет в абстрактном классе
2. написать итератор... но это будет еще хуже впихиваться в условия задачи (пишу не себе ;))... и походу этого делать не буду

Вот. Что собсно можно сделать еще?


--------------------
как корабль назовешь - то на нем и напишешь
PM MAIL WWW ICQ   Вверх
Lazin
Дата 14.12.2008, 21:13 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



Цитата(BSOD @  14.12.2008,  21:07 Найти цитируемый пост)
Вот. Что собсно можно сделать еще?

использовать статический полиморфизм, а не динамический было-бы логичней в данном случае
PM MAIL Skype GTalk   Вверх
BSOD
Дата 14.12.2008, 21:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 405
Регистрация: 1.11.2004
Где: Гомель

Репутация: нет
Всего: 3



Нееее, хотя бы потому, что это не подойдет под условие задачи еще больше, чем любой другой изврат...  :(


--------------------
как корабль назовешь - то на нем и напишешь
PM MAIL WWW ICQ   Вверх
Lazin
Дата 14.12.2008, 21:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



это не изврат, если ты хочешь реализзовать конструктор копирования, значит тебе нужна семантика значений, тоесть абстрактный базовый класс здесь совершенно не у дел.
конструктор копирования нельзя сделать виртуальным, соответственно в абстрактном базовом классе ему нет места, так как у него по определению нет состояния. 
PM MAIL Skype GTalk   Вверх
BSOD
Дата 14.12.2008, 21:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 405
Регистрация: 1.11.2004
Где: Гомель

Репутация: нет
Всего: 3



Почему же, если бы в базом класе были функции для доступа не только к первому элементу, но и ко всем, то все бы реализовывалось, т.е. скорее всего что-то вводить придется, вопрос - что...


--------------------
как корабль назовешь - то на нем и напишешь
PM MAIL WWW ICQ   Вверх
Alek86
Дата 14.12.2008, 21:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



можно использовать паттерн Посетитель
типа такого выйдет

есть StackParent и дети: Stack1, Stack2

Код

StackParent& StackParent::operator=(const StackParent& rhs) {
 rhs.CloneTo(*this);
}

void Stack1::CloneTo(Stack1& subj) {
 // реализация копирования из Stack1 в Stack1
}
void Stack1::CloneTo(Stack2& subj) {
 // реализация копирования из Stack2 в Stack1
}

void Stack2::CloneTo(Stack1& subj) {
 // реализация копирования из Stack1 в Stack2
}
void Stack2::CloneTo(Stack1& subj) {
 // реализация копирования из Stack2 в Stack2
}


Добавлено @ 21:46
то же и с copy constructor

хотя не совсем так - в моем случае интерфейс StackParent зависит от наследников
дальше думать  лень, но, вроде, Посетитель и эту проблему решает

Это сообщение отредактировал(а) Alek86 - 14.12.2008, 21:48


--------------------
user posted image    user posted image
PM MAIL   Вверх
BSOD
Дата 14.12.2008, 21:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 405
Регистрация: 1.11.2004
Где: Гомель

Репутация: нет
Всего: 3



Цитата

можно использовать паттерн Посетитель
типа такого выйдет
...


Тогда мы должны знать всех потомков...


--------------------
как корабль назовешь - то на нем и напишешь
PM MAIL WWW ICQ   Вверх
Alek86
Дата 14.12.2008, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



точно, надо выделить интерфейс Посетителя, который будет за тех потомков отвечать
подробнее - в инете, по запросу "паттерн Посетитель"


--------------------
user posted image    user posted image
PM MAIL   Вверх
mes
Дата 14.12.2008, 22:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(BSOD @  14.12.2008,  21:07 Найти цитируемый пост)
. В конструкторе копирования я использую виртуальную функцию clone, которую потом перегружаю в каждой реализации, но, в clone-то передается ссылка на Stack (наш интерфейс), чез который не особо-то и можно скопировать...


есть интерфейс стека, для копии вызываете виртуальную Clone, за реализацию которой ответственнен конкретный объект, у которого все  нужные методы присутствуют.
Так ? а в чем проблема то ?  smile 
Особенно не понял
Код

в clone-то передается ссылка на Stack (наш интерфейс),

а для чего собственно передается ?? this`a более чем достаточно. 

Это сообщение отредактировал(а) mes - 14.12.2008, 22:09


--------------------
PM MAIL WWW   Вверх
Alek86
Дата 14.12.2008, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



mes, если есть 2 потомка - stack1 и stack2, то между ними - 4 варианта копирования
если 3 потомка - 6 вариантов
и так далее
а вирт функция - только одна


--------------------
user posted image    user posted image
PM MAIL   Вверх
Lazin
Дата 14.12.2008, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 41
Всего: 154



вот поэтому в таких случаях не используют конструктор копирования. если твой стек поддерживает итераторы, то можно вместо метода clone, добавить методы begin, end и assign smile

Добавлено через 1 минуту и 50 секунд
Код

class StackImpl1;
class StackImpl2;

StackImpl1 s1;
...
StackImpl2 s2(s1.being(), s1.end());

или
Код

StackImpl2 s2;
s2.assign(s1.begin(), s1.end());

PM MAIL Skype GTalk   Вверх
mes
Дата 14.12.2008, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Alek86 @  14.12.2008,  22:09 Найти цитируемый пост)
mes, если есть 2 потомка - stack1 и stack2, то между ними - 4 варианта копирования

то есть надо чтоб 
Код

class IStack {...}
class Stack1 : public IStack {..}
class Stack2 : public IStack {..}

..
Stack1 st1;
Stack2 st2;
st1 = st2; // сработало это ?  

тогда Clone, то тут не при чем !

Это сообщение отредактировал(а) mes - 14.12.2008, 22:17


--------------------
PM MAIL WWW   Вверх
Alek86
Дата 14.12.2008, 22:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1299
Регистрация: 30.1.2007
Где: Киев

Репутация: 21
Всего: 25



с чего это стеку вдруг поддерживать итераторы?
можно, конечно, с пом pop, top, push скопировать, но это ж будет довольно неэкономично

Добавлено через 23 секунды
mes, да, к примеру


--------------------
user posted image    user posted image
PM MAIL   Вверх
mes
Дата 14.12.2008, 22:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(Alek86 @  14.12.2008,  22:16 Найти цитируемый пост)
да, к примеру 

если эту задача решать эффективно через полиморфизм базового класса, то без визитера не обойтись.
В другом случае каждый наследник, должен уметь себя создавать имея ссылку на базовый интерфейс.

Добавлено @ 22:25
Цитата(BSOD @  14.12.2008,  21:07 Найти цитируемый пост)
использовать ForEach и Insert... отлично, но мы не можем в ForEach передать функцию-член класса :(

а функтор можем передавать ? 

Это сообщение отредактировал(а) mes - 14.12.2008, 22:32


--------------------
PM MAIL WWW   Вверх
BSOD
Дата 14.12.2008, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 405
Регистрация: 1.11.2004
Где: Гомель

Репутация: нет
Всего: 3



Цитата

с чего это стеку вдруг поддерживать итераторы?
можно, конечно, с пом pop, top, push скопировать, но это ж будет довольно неэкономично


На самом деле это всего-лишь в 3 раза "неэкономичнее", чем просто копирование ;)... и этот вариант я тож рассматривал (на крайняк smile )... но.. но была проблема с тем, что копируем мы из константного объекта, т.е. никих pop()... но, т.к. на самом деле - это просто задача по проге, которую нужно сдать всему потоку, я узнал, что народ собирается просто заюзать typeid, если мы копируем из одного потомка в такой же, то статик_каст и копируем, иначе кидаем како-нить эксцепшн... но я так сделать не могу, ибо это совсем уж бред. Но. Вот прям только что я понял, что это можно использовать, что бы создать копию константного объекта, а потом ее уже через pop-push скопировать  smile 
Да, я понимаю, что это совсем жуткий изврат, но всеравно, ведь это будет работать (1), мы не будем менять ничего в абстрактном классе (2) и это даже не будет особо тормозить (!) smile
сорри, что я тут сам с собой нафлудил немного, эмоции smile

Добавлено через 1 минуту и 21 секунду
Цитата

а функтор можем передавать ? 


Эммм, а кстати да, как вариант... но всеравно, придется немного, да подправить базовый класс..


--------------------
как корабль назовешь - то на нем и напишешь
PM MAIL WWW ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1289 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.