Форум программистов, компьютерный форум CyberForum.ru

Массив указателей на классы - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
KnockKnock
 Аватар для KnockKnock
1 / 1 / 0
Регистрация: 04.11.2012
Сообщений: 11
07.11.2012, 12:58     Массив указателей на классы #1
Помогите, пожалуйста, понять ситуацию:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
enum COLOR {RED, GREEN, BLUE};
 
class Shape
{
protected:
    int m_x, m_y;
    COLOR m_color;
public:
    Shape(int x = 0, int y = 0, COLOR c = RED);
    virtual ~Shape(void);
    virtual void WhereAmI(void); // { cout << "In class Shape"; }
};
 
class Rect : public Shape
{
    int m_right, m_bottom;
 
public:
    Rect (int left = 0, int top = 0, int right = 0, int bottom = 0, COLOR c = RED);
    virtual ~Rect(void);
 
    virtual void WhereAmI(void); // { cout << "In class Rect"; }
};
 
int main ()
{
    Shape* pShapes = new Rect[10]; //1)
    Rect* pRects = new Rect[10]; //2)
 
    for (int i = 0; i < 10; i ++)
    {
        pShapes[i].WhereAmI (); //тут ошибки для i > 0
        pRects[i].WhereAmI (); // тут всё ок
 
    }
}
Почему первый вариант вызывает ошибку? Как правильно понимать эту конструкцию?
Создаём указатель базового класса на массив из 10 объектов производного класса?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
07.11.2012, 15:15     Массив указателей на классы #2
потому что цикл for шагает по массиву объектов Shape (т.к. указатель на Shape), в то время как в массиве содержатся объекты Rect(а размеры Shape и Rect разные). Можно привести указатель
C++
1
dynamic_cast<Rect*>(pShapes)[i].WhereAmI ();
KnockKnock
 Аватар для KnockKnock
1 / 1 / 0
Регистрация: 04.11.2012
Сообщений: 11
07.11.2012, 15:43  [ТС]     Массив указателей на классы #3
О, спасибо! Про преобразование типа указателя я не подумал...

Добавлено через 12 минут
Что-то я запутался... Как в данном случае вообще работает массив? При i=1 при преобразовании типа указателя считается правильное смещение относительно pShape? Тогда почему не работает такое вот:
C++
1
(pShapes + i*sizeof(Rect))->WhereAmI ();
В таком духе вообще можно получить нужный результат?
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
07.11.2012, 16:15     Массив указателей на классы #4
Думаю что нет. Это попытка подсунуть компилятору число байт на которые надо сместить указатель, но он принимает только тип указателя и число шагов i, и по этим параметрам сам вычисляет число байт для смещения. При i == 0 срабатывает правильно потому что указатель на виртуальную таблицу находится по адресу объекта(в самом начале объекта) .
KnockKnock
 Аватар для KnockKnock
1 / 1 / 0
Регистрация: 04.11.2012
Сообщений: 11
07.11.2012, 17:14  [ТС]     Массив указателей на классы #5
Ага, понятно, спасибо. Грубо говоря в теории, видимо, можно подобрать нужное количество байт, если очень приспичит... Это я так, для себя

И последнее: вот если такой вариант

C++
1
2
3
4
5
    Shape* ar[]={new Shape, new Rect, new Rect(r) };
        for (int i = 0; i < sizeof(ar)/sizeof(Shape*); i ++)
        {
            ar[i]->WhereAmI (); 
        }
Тут просто указатель на массив с указателями, вполне строгого размера, потому всё работает без преобразований (как и расчет максимального значения i), верно?

Добавлено через 27 минут
+совсем последнее
корректно чистить память так?
C++
1
2
3
4
5
Shape* pShapes = new Rect[10];//1)
Rect* pRects = new Rect[10];//2)
 
delete[] pShapes;
delete[] pRects;
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11800 / 6779 / 765
Регистрация: 27.09.2012
Сообщений: 16,831
Записей в блоге: 2
Завершенные тесты: 1
07.11.2012, 20:16     Массив указателей на классы #6
Цитата Сообщение от KnockKnock Посмотреть сообщение
Тут просто указатель на массив с указателями, вполне строгого размера, потому всё работает без преобразований (как и расчет максимального значения i), верно?
Да, указатели занимают в памяти одинаковое количество памяти.
Цитата Сообщение от KnockKnock Посмотреть сообщение
корректно чистить память так?
Да. Выделяете память под массив, освобождаете с помощью delete []
KnockKnock
 Аватар для KnockKnock
1 / 1 / 0
Регистрация: 04.11.2012
Сообщений: 11
07.11.2012, 20:30  [ТС]     Массив указателей на классы #7
Благодарю
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
07.11.2012, 21:13     Массив указателей на классы #8
да, однотипные указатели(на объекты, на ф-ции) имеют одинаковый размер поэтому такой цикл отработает. Освобождение правильное т.к. деструктор виртуальный.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11800 / 6779 / 765
Регистрация: 27.09.2012
Сообщений: 16,831
Записей в блоге: 2
Завершенные тесты: 1
07.11.2012, 21:17     Массив указателей на классы #9
Цитата Сообщение от igorrr37 Посмотреть сообщение
да, однотипные указатели(на объекты, на ф-ции) имеют одинаковый размер поэтому такой цикл отработает. Освобождение правильное т.к. деструктор виртуальный.
А можно пример не однотипных указателей, которые имеют разный размер?
igorrr37
 Аватар для igorrr37
1593 / 1221 / 118
Регистрация: 21.12.2010
Сообщений: 1,868
Записей в блоге: 7
07.11.2012, 22:21     Массив указателей на классы #10
Croessmah, насколько я понял стандарт такое не запрещает
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.11.2012, 22:33     Массив указателей на классы
Еще ссылки по теме:

C++ Задачка. массив указателей на одномерный массив
C++ Создание стека в виде массива указателей на разные классы
Использование указателей, классы, наследование C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
07.11.2012, 22:33     Массив указателей на классы #11
Все указатели имеют одинаковый размер.

Разный размер будет разве что если указателями считать и так называемые smart pointers.

Добавлено через 12 минут
Ну, хотя если говорить строго, то да. Там нет ничего, что говорило бы об одинаковом представлении указателей на разные типы. Возможность каста к void* и обратно косвенно намекает на это, но всё же не гарантирует.
Yandex
Объявления
07.11.2012, 22:33     Массив указателей на классы
Ответ Создать тему
Опции темы

Текущее время: 10:34. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru