Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

работа с классами в Си++

9.8K
02 октября 2005 года
eng
22 / / 02.10.2005
Имеется 4 вида фигуры: точка, круг, квадрат и правильный треугольник. Требуется создать программу, которая содержала бы список(динамический) из выше приведенных фигур и рисовала вращала, передвигала, увеличевала/уменьшала бы их на экране.
Я не могу понять как соеденить все объекты этих классов(точка, круг, квадрат и правильный треугольник) в список(динамический).
Подскажите кто знает.
276
02 октября 2005 года
Rebbit
1.1K / / 01.08.2005
Цитата:
Originally posted by eng
Я не могу понять как соеденить все объекты этих классов(точка, круг, квадрат и правильный треугольник) в список(динамический).



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

9.8K
03 октября 2005 года
eng
22 / / 02.10.2005
Цитата:
Originally posted by Rebbit
Тебе надо порождать ети обекты от базового класа с виртуальными функциями (смотри документацию по ООП). Делаеш масив указателей на базовый клас. Потом создаеш в динамической памяти екземпляри обектов тех класов что тебе нужны, а указатели на них запихиваеш в масив.



Я создал базовый класс и создал дочерние классы покаждой фигуре. У меня в базовом классе есть виртуальная функция paint(она рисует фигуру), которая переопределяется в каждом дочернем классе. Так если я сделаю список из объектов базового класса и буду вызывать функцию paint как компилятор поймёт к какому из дочерних классов относится эта функция(какую именно фигуру надо нарисовать). Или один базовый класс будет рисовать все фигуры?

9.3K
03 октября 2005 года
viv
21 / / 20.04.2005
Цитата:
Originally posted by eng
Я создал базовый класс и создал дочерние классы покаждой фигуре. У меня в базовом классе есть виртуальная функция paint(она рисует фигуру), которая переопределяется в каждом дочернем классе. Так если я сделаю список из объектов базового класса и буду вызывать функцию paint как компилятор поймёт к какому из дочерних классов относится эта функция(какую именно фигуру надо нарисовать). Или один базовый класс будет рисовать все фигуры?



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

3
03 октября 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by viv
Я думаю, что ты будешь приводить указатели на базовый класс к указателям на производный и соответственно работать с методами производных классов.


Тогда в чем смысл виртуальных методов?

Цитата:
Originally posted by eng

как компилятор поймёт к какому из дочерних классов относится эта функция(какую именно фигуру надо нарисовать)


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

В твоём же размышлении ошибка в том, что ты создаешь массив базовых объектов, а надо создавать массив указателей на базовый класс и присваивать им значения указывающие на созданные объекты производных классов.

9.3K
03 октября 2005 года
viv
21 / / 20.04.2005
Цитата:
Originally posted by Green
Тогда в чем смысл виртуальных методов?


Если производных классов несколько и имя метода, одинаково, и список формальных параметров совпадает, то как компилятор,без явного приведения к типу, может узнать, метод какого класса вызывать?

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

259
03 октября 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by viv
Если производных классов несколько и имя метода, одинаково, и список формальных параметров совпадает, то как компилятор,без явного приведения к типу, может узнать, метод какого класса вызывать?

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


Молодой человек. Внимательней читайте посты. Вам же Green написал чистым русским языком: Массив указателей, а не массив объектов.

9.3K
03 октября 2005 года
viv
21 / / 20.04.2005
Цитата:
Originally posted by AlexandrVSmirno
Молодой человек. Внимательней читайте посты. Вам же Green написал чистым русским языком: Массив указателей, а не массив объектов.


Это Вы внимательнее читайте.
Я с самого начала про указатели писал, а что вам надо понять вообще не могу.
Ко мне относилась только первая фраза грина и то не могу понять, к чему она была!

3
03 октября 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by viv
Если производных классов несколько и имя метода, одинаково, и список формальных параметров совпадает, то как компилятор,без явного приведения к типу, может узнать, метод какого класса вызывать?


Без явного приведения чего?
Указателя на базовый класс к указателю на производный?
Совершенно не нужно приводить, если работа идет через виртуальные методы. Для того они и есть.
Компилятор узнает по таблице виртуальных методов.

Цитата:
Originally posted by viv

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


Это применение, а не цель.
Цель - отвязать интерфейс от реализации.

259
03 октября 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by viv
Это Вы внимательнее читайте.
Я с самого начала про указатели писал, а что вам надо понять вообще не могу.
Ко мне относилась только первая фраза грина и то не могу понять, к чему она была!


Судя по вашему посту:

Цитата:
Если производных классов несколько и имя метода, одинаково, и список формальных параметров совпадает, то как компилятор,без явного приведения к типу, может узнать, метод какого класса вызывать?


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

9.3K
04 октября 2005 года
viv
21 / / 20.04.2005
Цитата:
Originally posted by AlexandrVSmirno
Судя по вашему посту:

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



Я не обижаюсь.
В чем прав-то?!
Так я и не понял Ваших ко мне претензий...
И при чем здесь массив объектов?
Ладно, будем считать, что мы друг друга не допоняли.
И все же хотелось бы у грина выяснить в частном порядке, как он это все видит...

259
04 октября 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by viv
Я не обижаюсь.
В чем прав-то?!
Так я и не понял Ваших ко мне претензий...
И при чем здесь массив объектов?
Ладно, будем считать, что мы друг друга не допоняли.
И все же хотелось бы у грина выяснить в частном порядке, как он это все видит...


Вот выдержка из учебника по ООП.

3.5.1 Виртуальные функции

В ООП полиморфизм достигается не только описанным выше механизмом наследования и перегрузки методов родителя, но и виртуализацией, позволяющей родительским функциям обращаться к функциям потомков. Полиморфизм реализуется через архитектуру класса, но полиморфными могут быть только функции-члены.

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

Позднее связывание не подразумевает явного приведения типов. На то оно и позднее. Это вообще стандартный механизм ООП для реализации абстракций и классов - контейнеров. Понимание этого механизма приводит нас к выводу, что достаточно ссылки на базовый класс, для того, чтобы организовать список для классов потомков. А явное приведение в этом случае не нужно, а за частую и невозможно.

362
04 октября 2005 года
_kolyan
339 / / 03.12.2002
Цитата:
Originally posted by viv
как он это все видит...



Все ту очень просто, вам толкуют, а вы на людей бросаетесь :)

1) Создаете базовай класс, например "фигура"
2) Создаете в нем виртуальную функцию "рисовать"
3) Создаете производные классы "квадрат", "круг" и т.п.
4) В каждом производном классе определяете функцию "рисовать"
5) Создаете сколько надо, каких надо объектов - квадратов, кругов и т.п.
6) Складываете указатели на эти объекты в массив, в список, в вектор - куда больше понравится.
7) Когда надо перерисовать, о перебираете эти указатели, приводите из к указателю на базовай класс "фигура" (в листе, например, они как void* лежат), и вызываете по этому указателю функцию "рисовать"
8) Наслаждаетесь как рисуются разные объекты.

3
04 октября 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by viv
И все же хотелось бы у грина выяснить в частном порядке, как он это все видит...


Видит решение задачи топика?
Вот так:

Код:
#include<list>

class Figure
{
public:
  virtual void draw() = 0;
};

class Circle :public Figure
{
public:
  void draw()
  {
    // implementation
  }
};

class Box :public Figure
{
public:
    void draw()
    {
        // implementation
    }
};

int main()
{
    std::list<Figure*> figures;

    // Создание и добавление фигур
    figures.push_back(new Circle);
    figures.push_back(new Box);
    // и т.д.

    // Прорисовка
    for(std::list<Figure*>::iterator it = figures.begin();
        it != figures.end(); ++it)
    {
        (*it)->draw();
    }
}
3
04 октября 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by _kolyan

7) Когда надо перерисовать, о перебираете эти указатели, приводите из к указателю на базовай класс "фигура" (в листе, например, они как void* лежат), и вызываете по этому указателю функцию "рисовать"


Только этот пункт неверен.
Зачем хранить void*, а потом преобразовывть его к указателю на базовый класс?
Я уже не раз говорил, что в С++ можно и нужно обходится вообще без void*.

В остальном всё верно и именно так показывается в моём примере.

362
04 октября 2005 года
_kolyan
339 / / 03.12.2002
Цитата:
Originally posted by Green
Зачем хранить void*, а потом преобразовывть его к указателю на базовый класс?



Я просто имел ввиду VCL'ный TList. Конечно лучше сразу хранить указатели на базовый класс.

259
04 октября 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by _kolyan
Я просто имел ввиду VCL'ный TList. Конечно лучше сразу хранить указатели на базовый класс.


В TList тоже можно спокойно обойтись без void*

362
04 октября 2005 года
_kolyan
339 / / 03.12.2002
Цитата:
Originally posted by AlexandrVSmirno
В TList тоже можно спокойно обойтись без void*



Может и можно, может и спокойно, я не знаю как.
Поделитесь секретом, если не жалко :)

259
04 октября 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by _kolyan
Может и можно, может и спокойно, я не знаю как.
Поделитесь секретом, если не жалко :)


Не жалко:

Add, Count, Items example

Код:
void __fastcall TForm1::Button1Click(TObject *Sender)

{
  PAList AStruct;
  TList *MyList = new TList;
  // fill the TList
  AStruct = new TAList;
  AStruct->I = 100;
  AStruct->C = 'Z';
  MyList->Add(AStruct);
  AStruct = new TAList;
  AStruct->I = 100;
  AStruct->C = 'X';
  MyList->Add(AStruct);
 
  // Go through the list, writing the elements to the
  // canvas of a paintbox component.
  int Y = 10; // position on canvas
  for (int i = 0; i < MyList->Count; i++)

  {
    AStruct = (PAList) MyList->Items;
    PaintBox1->Canvas->TextOut(10, Y, IntToStr(AStruct->I));
    Y += 30;  // Increment Y Value again
    PaintBox1->Canvas->TextOut(10, Y, AStruct->C);
    Y += 30;  //Increment Y Value
  }

  // Clean up – must free memory for the items as well as the list
  for (int i = 0; i < MyList->Count; i++)
  {
    AStruct = (PAList) MyList->Items;
    delete AStruct;
  }
  delete MyList;

}
362
04 октября 2005 года
_kolyan
339 / / 03.12.2002
Цитата:
Originally posted by AlexandrVSmirno
Не жалко:



Не понял, честно говоря. Вот я вижу преобразование элемента из void* к указателю некоторого другого типа:

 
Код:
AStruct = (PAList) MyList->Items;


Я разве не об этом говорил.
259
04 октября 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by _kolyan
Не понял, честно говоря. Вот я вижу преобразование элемента из void* к указателю некоторого другого типа:
 
Код:
AStruct = (PAList) MyList->Items;


Я разве не об этом говорил.


Значит я не понял. Я думал, что ты имеешь ввиду примерно следующее:

 
Код:
void* pStruct = MyList->Items;


Зы: А то, что они в TList определены как void*. Ну куда же от этого денешься.
3
04 октября 2005 года
Green
4.8K / / 20.01.2000
Цитата:
Originally posted by AlexandrVSmirno
Зы: А то, что они в TList определены как void*. Ну куда же от этого денешься.


Использовать STL :D

585
04 октября 2005 года
honeybeer
297 / / 06.09.2004
 
Код:
AStruct = (PAList) MyList->Items;

За такой reinterpret_cast обычно бьют :D
9.3K
04 октября 2005 года
viv
21 / / 20.04.2005
Да, приводить к указателю на производный класс необязательно.
585
04 октября 2005 года
honeybeer
297 / / 06.09.2004
Цитата:
Originally posted by viv
Да, приводить к указателю на производный класс необязательно.


Я вообще-то не совсем это имел ввиду. Такое преобразование можно делать если человек твердо уверен, что void* указывает на объект того типа к которому производится приведение, но так как void* может указывать на что угодно, то и результатом может быть что угодно.

7.0K
18 октября 2005 года
Salavat
20 / / 01.03.2005
Цитата:
Originally posted by eng
Имеется 4 вида фигуры: точка, круг, квадрат и правильный треугольник. Требуется создать программу, которая содержала бы список(динамический) из выше приведенных фигур и рисовала вращала, передвигала, увеличевала/уменьшала бы их на экране.
Я не могу понять как соеденить все объекты этих классов(точка, круг, квадрат и правильный треугольник) в список(динамический).
Подскажите кто знает.



Придеться поговорить с твоим бородатым преподом из угату!!! и тебе пипец придет!!)))

276
18 октября 2005 года
Rebbit
1.1K / / 01.08.2005
Цитата:
Originally posted by Salavat
Придеться поговорить с твоим бородатым преподом из угату!!! и тебе пипец придет!!)))



Не знаю как у Вас, но у нас за такое постукивание и инвалидом могут сделать. Главное потом и не докажеш что не сам з третьего етажа упал :D

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог