Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.80
KnockKnock
1 / 1 / 0
Регистрация: 04.11.2012
Сообщений: 11
#1

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

07.11.2012, 12:58. Просмотров 1478. Ответов 10
Метки нет (Все метки)

Помогите, пожалуйста, понять ситуацию:
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 объектов производного класса?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.11.2012, 12:58
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Массив указателей на классы (C++):

Массив указателей на неродственные классы - C++
Возможно ли создать массив указателей на экземпляры классов, не имеющих общего родительского?

Массив указателей на производные классы - C++
Здравствуйте, есть базовый класс строка mystring class mystring // Опишем базовый класс строки { protected: char *p; ...

Классы. Наследование, массив указателей, очистка памяти - C++
Разбираюсь с классами в си++. Имеется следующий код: header.h ...... class Circle :public Figure { public: void show(); }; ...

Массив указателей на массив строк и сортировка массива указателей - C++
Добрый день. Поступил вопрос. Есть задача. У нас встроенный массив char mass;.Мы вводим строки до тех пор, пока не будет заполнен массив...

по поводу указателей. Как правильно задавать массив указателей и его удалять? - C++
Т.е., например создаю указатель: TPoint *p_Point=NULL; а если массив? TPoint *p_MassPoint; //=?; как массив обнулить не ясно ...

Создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей - C++
Задача: создать специфицированный шаблон функции, принимающей массив указателей на char и количество самих указателей. Вернуть адрес...

10
igorrr37
1648 / 1276 / 133
Регистрация: 21.12.2010
Сообщений: 1,932
Записей в блоге: 7
07.11.2012, 15:15 #2
потому что цикл for шагает по массиву объектов Shape (т.к. указатель на Shape), в то время как в массиве содержатся объекты Rect(а размеры Shape и Rect разные). Можно привести указатель
C++
1
dynamic_cast<Rect*>(pShapes)[i].WhereAmI ();
2
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 ();
В таком духе вообще можно получить нужный результат?
0
igorrr37
1648 / 1276 / 133
Регистрация: 21.12.2010
Сообщений: 1,932
Записей в блоге: 7
07.11.2012, 16:15 #4
Думаю что нет. Это попытка подсунуть компилятору число байт на которые надо сместить указатель, но он принимает только тип указателя и число шагов i, и по этим параметрам сам вычисляет число байт для смещения. При i == 0 срабатывает правильно потому что указатель на виртуальную таблицу находится по адресу объекта(в самом начале объекта) .
1
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;
0
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
07.11.2012, 20:16 #6
Цитата Сообщение от KnockKnock Посмотреть сообщение
Тут просто указатель на массив с указателями, вполне строгого размера, потому всё работает без преобразований (как и расчет максимального значения i), верно?
Да, указатели занимают в памяти одинаковое количество памяти.
Цитата Сообщение от KnockKnock Посмотреть сообщение
корректно чистить память так?
Да. Выделяете память под массив, освобождаете с помощью delete []
1
KnockKnock
1 / 1 / 0
Регистрация: 04.11.2012
Сообщений: 11
07.11.2012, 20:30  [ТС] #7
Благодарю
0
igorrr37
1648 / 1276 / 133
Регистрация: 21.12.2010
Сообщений: 1,932
Записей в блоге: 7
07.11.2012, 21:13 #8
да, однотипные указатели(на объекты, на ф-ции) имеют одинаковый размер поэтому такой цикл отработает. Освобождение правильное т.к. деструктор виртуальный.
0
Croessmah
Ушел
Эксперт CЭксперт С++
13557 / 7707 / 872
Регистрация: 27.09.2012
Сообщений: 18,996
Записей в блоге: 3
Завершенные тесты: 1
07.11.2012, 21:17 #9
Цитата Сообщение от igorrr37 Посмотреть сообщение
да, однотипные указатели(на объекты, на ф-ции) имеют одинаковый размер поэтому такой цикл отработает. Освобождение правильное т.к. деструктор виртуальный.
А можно пример не однотипных указателей, которые имеют разный размер?
0
igorrr37
1648 / 1276 / 133
Регистрация: 21.12.2010
Сообщений: 1,932
Записей в блоге: 7
07.11.2012, 22:21 #10
Croessmah, насколько я понял стандарт такое не запрещает
0
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
07.11.2012, 22:33 #11
Все указатели имеют одинаковый размер.

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

Добавлено через 12 минут
Ну, хотя если говорить строго, то да. Там нет ничего, что говорило бы об одинаковом представлении указателей на разные типы. Возможность каста к void* и обратно косвенно намекает на это, но всё же не гарантирует.
1
07.11.2012, 22:33
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.11.2012, 22:33
Привет! Вот еще темы с ответами:

Создать специализацию для шаблона, которая принимает массив указателей на строки и количество этих указателей - C++
Нужно создать специализацию для шаблона, которая принимает массив указателей на строки и количество этих указателей. Эта специализация...

Массив из указателей на масив из указателей на массив из int) - C++
Доброго времени суток! Возникла проблема - как на C++ создать массив из указателей на массив из указателей на int? То есть массив из n...

Использование указателей, классы, наследование - C++
Абсолютное незнание темы и завалы на учебе не дают начать исправлять эту задачу на предмет использования указателей... помогите исправить...

Неявное приведение указателей на классы - C++
Всем привет! Обнаружилась вот такая нестыковочка: имеем интерфейсный класс IIn. И имеем класс-наследник ExtIn : public IIn далее...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.