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

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

Страниц: 1 ... 9 10 [11] 12 13   Вниз
  Печать  
Автор Тема: Как писать ООП программы?  (Прочитано 86726 раз)
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #150 : Февраль 28, 2014, 18:43 »

Потому как базовый класс Shape не знает метода setRadius()
И по логике, не обязан, ибо не у всех фигур есть радиус Улыбающийся
Записан

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

Сообщений: 11445


Просмотр профиля
« Ответ #151 : Февраль 28, 2014, 18:48 »

Потому как базовый класс Shape не знает метода setRadius()
То конечно хороший вопрос, но пусть сначала вынесет генерацию из конструктора и хоть как-то наладит взаимодействие классов. А то пока только песиков наводит.
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #152 : Февраль 28, 2014, 18:50 »

Пусть учится
Записан
8Observer8
Гость
« Ответ #153 : Февраль 28, 2014, 18:54 »

Получается, что при передачи в функцию через указатель на базовый класс полиморфизм работает, а если в том же блоке, то нет? Непонятно...
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #154 : Февраль 28, 2014, 18:58 »

...а если в том же блоке...
что в том же блоке?
Записан
8Observer8
Гость
« Ответ #155 : Февраль 28, 2014, 19:05 »

Я имею виду, что объявляем указатель на базовый класс и инициализируем его объектом производного:

Код
C++ (Qt)
   std::shared_ptr<myShapes::Shape> pc(new myShapes::Circle(50.0));
   pc->setRadius(25.0);
 

И это не работает. А если так же с функцией, то работает:

Код
C++ (Qt)
void Viewer::draw(std::shared_ptr<myShapes::Shape> ps, int xOffset, int yOffset)
 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #156 : Февраль 28, 2014, 19:21 »

А если так же с функцией, то работает:
Да ладно. Подмигивающий
Попробуйте там вызвать setRadius.

Если вы хотите пользоваться частным (не общим) функционалом производного класса, то придется приводить указатель к этому классу.
« Последнее редактирование: Февраль 28, 2014, 19:25 от Old » Записан
8Observer8
Гость
« Ответ #157 : Февраль 28, 2014, 19:50 »

Значит, я полиморфизм неправильно понял. Видимо, перепутал с ситуацией, когда в производном переопределяется функция с ключевым словом "virtual".

Статический полиморфизм (с шаблонами) пока в сторону. Нужно лучше динамический проработать.

А как привести?

Код
C++ (Qt)
(myShapes::Shape)pc->setRadius(25.0);
 
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #158 : Февраль 28, 2014, 19:53 »

А как привести?
std::dynamic_pointer_cast<T>( ptr );

И лучше сишные касты оставить для си.
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #159 : Февраль 28, 2014, 20:02 »

А как привести?
std::dynamic_pointer_cast<T>( ptr );

И лучше сишные касты оставить для си.

Правило 27 Улыбающийся
Цитировать
Предпочитайте приведения в стиле C++ старому стилю. Их легче увидеть, и они более избирательны.
Записан

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

Сообщений: 11445


Просмотр профиля
« Ответ #160 : Февраль 28, 2014, 20:05 »

Код
C++ (Qt)
void Viewer::draw(std::shared_ptr<myShapes::Shape> ps, int xOffset, int yOffset)
 
Сама по себе эта запись ничем не ошибочна, но ЗАЧЕМ программист так делал? Если (допустим) я не в теме, то решил бы просто:

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

Если же программист не планировал этого то ему следовало ограничиться простым
Код
void Viewer::draw(Shape * ps, int xOffset, int yOffset)
 
Не засоряя мозги ни себе ни людям. Принцип "кашу маслом не испортишь" в программировании неприменим
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #161 : Февраль 28, 2014, 20:07 »

но ЗАЧЕМ программист так делал?
Потому что программист использует shared_ptr. Улыбающийся

Если (допустим) я не в теме, то...
нужно пойти подучиться.
Записан
8Observer8
Гость
« Ответ #162 : Февраль 28, 2014, 20:15 »

А как привести?
std::dynamic_pointer_cast<T>( ptr );

И лучше сишные касты оставить для си.


Огромное спасибо! Работает!

Вот что-то радиус не меняет.  Грустный

Правило 27 Улыбающийся
Цитировать
Предпочитайте приведения в стиле C++ старому стилю. Их легче увидеть, и они более избирательны.

Спасибо! Я пропустил это правило. Улыбающийся Не подряд читаю. А только если что-то нужно. Вот сейчас нужно, и надо прочитать Улыбающийся


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

Если же программист не планировал этого то ему следовало ограничиться простым
Код
void Viewer::draw(Shape * ps, int xOffset, int yOffset)
 
Не засоряя мозги ни себе ни людям. Принцип "кашу маслом не испортишь" в программировании неприменим

В моём viewer'e хранится массив указателей на внешние объекты. Пользователь может вызвать delete для внешних объектов. shared_ptr спасает тем, что в нём есть счётчик ссылок. Пока есть хоть одна ссылка на объект, то он не удалится.

Viewer'у необходимо перерисовывать пока программа работает. Вот ситуация, когда объекты удалились до их показа:

Код
C++ (Qt)
int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
 
   Viewer viewer;
   viewer.resize(400, 200);
 
   myShapes::Shape *pr1 = new myShapes::Rectangle(5.0, 10.0);
   myShapes::Shape *pr2 = new myShapes::Rectangle(5.0, 10.0);
   myShapes::Shape *pr3 = new myShapes::Rectangle(5.0, 10.0);
   myShapes::Shape *pr4 = new myShapes::Rectangle(5.0, 10.0);
   myShapes::Shape *pr5 = new myShapes::Rectangle(5.0, 10.0);
 
   viewer.addForPainting(*pr1);
   viewer.addForPainting(*pr2);
   viewer.addForPainting(*pr3);
   viewer.addForPainting(*pr4);
   viewer.addForPainting(*pr5);
 
   delete pr1;
   delete pr2;
   delete pr3;
   delete pr4;
   delete pr5;
 
   viewer.show();
   return a.exec();
}
 
« Последнее редактирование: Февраль 28, 2014, 20:17 от 8Observer8 » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #163 : Февраль 28, 2014, 20:19 »

И лучше сишные касты оставить для си.
Предпочитайте приведения в стиле C++ старому стилю. Их легче увидеть, и они более избирательны.
Также очень популярное правило лишь по той причине что.. "его легко выучить"  Улыбающийся Ну правда, стоит лишь запомнить "С приведение = плохо. С++ приведение = хорошо" - и все (якобы) освоил Улыбающийся  В действительности "С приведение" с полным правом может считаться "expert mode" - все оно прекрасно сделает, вот только если неправильно - нет ошибки, ничего не скажет. Ну так ведь на то и "эксперт"  Улыбающийся
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #164 : Февраль 28, 2014, 20:21 »

Вот что-то радиус не меняет.  Грустный
Так он и не будет. У вас весь просчет окружности происходит в конструкторе. Вам нудно вынести его в отдельный метод и вызывать его после любого изменения радиуса.
Записан
Страниц: 1 ... 9 10 [11] 12 13   Вверх
  Печать  
 
Перейти в:  


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