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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Передача в метод не наследника, а родителя. Как, получить доступ к свойствам наследника? 
:(
    Опции темы
Gunslinger
Дата 18.11.2009, 09:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Это вроде композицией называется. На примере сериализации. От этого класса есть какое-то количество наследников, которые все нужно сериализовать. Ошибочно реализовывать метод сериализации для каждого наследника, вместо этого создается один метод сериализации, но с аргументом не какого-либо наследника, а их родителя. Тогда в такой метод можно передавать любого наследника. Вопрос: в таком случае доступ к свойствам и методам наследника будет? Ведь наследник - это свойства\методы родителя + свои, наследник передается через аргумент с типом его родителя, то есть, свойства\методы наследника не доступны.. Или я ошибаюсь?

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


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


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

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



Цитата(Gunslinger @  18.11.2009,  08:56 Найти цитируемый пост)
Это вроде композицией называется.

нет, не это.

Цитата(Gunslinger @  18.11.2009,  08:56 Найти цитируемый пост)
Ошибочно реализовывать метод сериализации для каждого наследника, вместо этого создается один метод сериализации, но с аргументом не какого-либо наследника, а их родителя.

имхо, или не так описали, или не так поняли.
 smile 

Цитата(Gunslinger @  18.11.2009,  08:56 Найти цитируемый пост)
Вопрос: в таком случае доступ к свойствам и методам наследника будет?

либо базовый класс должен обладать необходимым интерфейсом, 
либо нужно привести базу к типу наследника.

 smile 


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


Опытный
**


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

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



Цитата(mes @  18.11.2009,  10:16 Найти цитируемый пост)
имхо, или не так описали, или не так поняли.

ага, писал по памяти. Сейчас найти ту информацию не могу. Нечто вроде:
Код

class Pet;
class Dog: Pet;
class Cat: Pet;
......
class N: Pet;

class PetHouse;
PetHouse house1; // есть метод isHomeCorrect(Pet& pet), смысл не корректен (придумывал на ходу), главное - должен вызываться для каждого наследника 
house1.isHomeCorrect(Dog); 
house1.isHomeCorrect(Cat);
......
house1.isHomeCorrect(N);

Вопрос: в таком варианте добавочные свойства\методы наследников Dog, Cat,.., N не доступны, раз они передаются по типу Pet? И если не доступны, как сделать так, чтобы были доступны и при этом сохранить такой тип аргумента, чтобы не реализовывать метод для каждого наследника?

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


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


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

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



Цитата(Gunslinger @  18.11.2009,  09:40 Найти цитируемый пост)
И если не доступны, как сделать так, чтобы были доступны 



"обычный" полиморфизм
двойная диспатчеризация (она же паттерн визитер)
dynamic_cast



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


Опытный
**


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

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



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


--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
Gunslinger
Дата 18.11.2009, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(mes @  18.11.2009,  11:43 Найти цитируемый пост)
"обычный" полиморфизм
двойная диспатчеризация (она же паттерн визитер)
dynamic_cast

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

Цитата(KelTron @  18.11.2009,  11:52 Найти цитируемый пост)
Так если у тебя логика функции отличается для разных типов объектов,

Само собой логика одна и та же, поэтому плодить метод бессмысленно, а как правильно - не знаю.



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


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


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

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



Цитата(Gunslinger @  18.11.2009,  12:53 Найти цитируемый пост)
про обычный полиморфизм не понял, как это возможно, может быть вы имеете ввиду виртуализацию? по остальному - гуглю.

тогда тоже в гугль (или сразу в книжку) - динамический полиморфизм



Цитата(Gunslinger @  18.11.2009,  12:53 Найти цитируемый пост)
Само собой логика одна и та же, поэтому плодить метод бессмысленно, а как правильно - не знаю.

ну для начала приведите пример более точно отражающий вашу задачу, чем пример выше.
smile


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


Опытный
**


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

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



Цитата(mes @  18.11.2009,  14:38 Найти цитируемый пост)
тогда тоже в гугль (или сразу в книжку) - динамический полиморфизм

Я про виртуальные функции и говорил.

Цитата(mes @  18.11.2009,  14:38 Найти цитируемый пост)
ну для начала приведите пример более точно отражающий вашу задачу, чем пример выше.

Пример привести не могу, т.к. конкретной задачи нет. Интересовало вот что: если мы передаем в функцию с параметром типа Родитель аргумент с типом ПотомокЭтогоРодителя, то в функции у нас будет доступ к свойствам и методам  потомка или только к унаследованным от Родителя?
Код

класс Родитель;
класс Потомок: Родитель;
указатель объект=new Потомок;

прототип:
функция\метод(Родитель объект);

в коде:
функция\метод(Потомок);



Это сообщение отредактировал(а) Gunslinger - 19.11.2009, 09:36
PM MAIL   Вверх
KelTron
Дата 19.11.2009, 13:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(Gunslinger @  19.11.2009,  09:35 Найти цитируемый пост)
то в функции у нас будет доступ к свойствам и методам  потомка или только к унаследованным от Родителя?

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




--------------------
Тысячами незримых нитей обвивает тебя Закон. Разрубишь одну - преступник. Десять - смертник. Все - Бог.
Эвенгар Салладорский, основатель Школы Тьмы.
PM MAIL   Вверх
mes
Дата 19.11.2009, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Gunslinger @  19.11.2009,  08:35 Найти цитируемый пост)
Пример привести не могу, т.к. конкретной задачи нет. Интересовало вот что: если мы передаем в функцию с параметром типа Родитель аргумент с типом ПотомокЭтогоРодителя, то в функции у нас будет доступ к свойствам и методам  потомка или только к унаследованным от Родителя?

ну вот Вам  тогда общие примеры, может поможет наглядно разобраться:

http://forum.vingrad.ru/index.php?showtopi...t&p=1715082
http://forum.vingrad.ru/index.php?showtopi...t&p=1692823

(ну вот пришлось вместо Вас поиск пользовать... smile )

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


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


Опытный
**


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

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



mes, извините, что отнял столько времени с поиском -  я в гугле искал, а по форуму поискать не додумался.
Читаю ссылки, что вы дали. Понял, что в понимании низкого уровня пробел. Пока другой вопрос: про указатели и адреса памяти. Какой смысл писать тип указателя, тем более структуры или класса? Указатель же хранит адрес ячейки памяти, а структура\класс со своими полями\методами занимает больше, чем одна ячейка... Или эта инфа для компилятора?

з.ы. под ячейкой я понимаю 1 байт.

Это сообщение отредактировал(а) Gunslinger - 19.11.2009, 16:36
PM MAIL   Вверх
mes
Дата 19.11.2009, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(Gunslinger @  19.11.2009,  15:34 Найти цитируемый пост)
mes, извините, что отнял столько времени с поиском -  я в гугле искал, а по форуму поискать не додумался.

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

Добавлено через 5 минут и 29 секунд
Цитата(Gunslinger @  19.11.2009,  15:34 Найти цитируемый пост)
Или эта инфа для компилятора?

Да.. но не только для компилятора, но и для удобства программиста.


Это сообщение отредактировал(а) mes - 19.11.2009, 16:56


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


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


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

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



Цитата(Gunslinger @  19.11.2009,  15:34 Найти цитируемый пост)
Указатель же хранит адрес ячейки памяти 

нет указатель нечто больше.. адрес то можно хранить и в void *, но тогда статическая информация  о типе (в частности об интерфейсе  доступа к объекту) будет утеряна.

Цитата(Gunslinger @  19.11.2009,  15:34 Найти цитируемый пост)
под ячейкой я понимаю 1 байт. 

Ну взять хотя бы  инкрементацию указателя.. Она изменяет его значение не на один байт, а на размер объекта типа.
 smile 

P.S. не забывайте про правило форума :один вопрос - одна тема.


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


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


Опытный
**


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

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



Цитата(mes @  19.11.2009,  17:12 Найти цитируемый пост)
P.S. не забывайте про правило форума :один вопрос - одна тема.

Понял, создал отдельную: "Механика работы указателей" -- 
http://forum.vingrad.ru/forum/act-ST/f-92/...0/unread-1.html



Это сообщение отредактировал(а) Gunslinger - 20.11.2009, 10:37
PM MAIL   Вверх
mes
Дата 20.11.2009, 12:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Тип это некая абстракция языка позволяющая определить поведение объектов и взаимодействие между ними. 
C++ обладает статической типизацией, т.е. вся информация о типах существует только в режиме компиляции. 

Типы бывают встроенными (int, double...) и пользовательскими (struct, class, union). 

Тип переменной проассоциирован с ней на протяжении всей ее видимости. т.е. программист пишет int i; и в дальнейшем везде где используется эта i  компилятор знает, что она int.

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

вместо того чтоб писать :

void f_int_double (a,b) {...}
void f_double_ int (a,b) {...}

var<4> a; //4 байта , условное int
var<8> b; //8 байт, условное  double
f_int, double(a,b); 
f_double_int(b,a);
//f_double_int(a,b); // ошибка которая не будет обнаружена компилятором


и самому помнить что хранит переменная и как с этим работать,  
мы перегружаем эту работу на компилятор и пишем:

void f(int a, double b) {..}
void f(double b, int a) {..}

int a;
int b;
f(a,b); // 
f(b,a); // компилятор сам выберет нужную функцию на основе типов.

В C++ перегрузка существует не  только для функций, но и для операторов. т.е. в выражении a+b; выберется к примеру  op+<int, int>() или op+<double,double>()

Однако одной перегрузки нeдостаточно для удобной работы, так как нам пришлось бы определять кучу одинаковых функций для всех нужных типов. Для решения этой проблемы в c++ введено приведение типов. (Оно бывает явное и неявное, а также делится по уровням продвижение, стандарное и пользовательское преобразования).
теперь для выражения char_+int_ не  нужно реализовывать отдельный плюс, а можно привести к виду int_ + int_. То же касается и пользовательских типов, для которых программист может определить нужные преобразования.

Также благодаря знаниям o типе известен и размер объекта, и нам не нужно следить вручную.

По типам вроде бы все, пойдем дальше.. Чтоб работать с объектом в С++ существуют временный объект, переменная, ссылка, и указатель.
Каждая это представление (еще одно помимо типа)  некой абстракции для пользования объектом. 

Указатель это такой объект, который хранит адрес другого объекта или 0, позволяет итерацию (размер шага которой определяется типом указателя), а также предоставляет доступ путем разъименования или через operator->()

Ссылка это сущность (не объект) которая проассоциирована с адресом объекта и предоставляет к нему доступ посредством operator.()


Ну кажется все.. Надеюсь объяснение не сильно отличается от истины smile



--------------------
PM MAIL WWW   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0576 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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