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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
Alex1234
13 / 13 / 0
Регистрация: 11.02.2011
Сообщений: 55
#1

Глупый вопрос по указателям? - C++

11.02.2011, 12:08. Просмотров 1170. Ответов 25
Метки нет (Все метки)

Здравствуйте! Подскажите как это работает? Правильно ли я понимаю?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
struct A
{
};
 
struct B: public A
{
    int var1;
    int var2;
};
 
int main(int argc, char *argv[])
{
    A* x = new A;            //Памяти выделяется на объект от A
    B* y = (B*)x;
    y->var2 = 5;              //Пишет не в свою память?
    ((B*)x)->var2 = 5;      //Это эквивалент?
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.02.2011, 12:08     Глупый вопрос по указателям?
Посмотрите здесь:

Оч глупый вопрос - C++
вот вместо цифры 1 как поставить переменную p->Bitmap->SaveToFile("C:\\bm\\rf\\1.bmp"); до этого баловался только с борландом.. поэтому...

Вопрос по указателям - C++
Ребят, простите за такую глупость, но вот не знаю как ответить на чётко поставленный преподавателем вопрос : "Как зная указатель на...

Вопрос по указателям - C++
В учебнике Дейтелов нашел код: void convertToUppercase(char *); int main() { char string = "characters and $32.98"; ...

Глупый вопрос по шаблонам - C++
Доброе время суток! Я достаточно опытный программист Java, но жизнь, как говорится, заставила переквалифицироваться на C++, причем,...

Извините за глупый вопрос. - C++
Как в С++ записывается "и"? (Например в Pascal это "and"). И как записать это в условие типа: if (N<1000) "и" (N>100) { bla bla bla...

простой и глупый вопрос - C++
Да, вопрос немного глуповат, но в нете так ничего и не нашла. Либо просто вводила не то для поиска. Не знаю короче. Суть вопроса: У меня...

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
11.02.2011, 12:17     Глупый вопрос по указателям? #2
C++
1
2
3
4
A* x = new A; // Создаётся указатель на объект A (на экземпляр класса A) и по этому указателю выделяется память, достаточная для хранения объекта A
B* y = (B*)x; //Создаётся указатель на тот же объект, причём, через него с этой переменной можно будет работать как с объектом B
y->var = 5; // Пишет в поле var по адресу объекта по адресу x, (или y, так как адреса эти равны), считая его экземпляром класса B
((B*)x)->var = 5; // То же самое.
.

Добавлено через 3 минуты
Это обычное неявное приведение типа, ничего хитрого здесь нет.
Alex1234
13 / 13 / 0
Регистрация: 11.02.2011
Сообщений: 55
11.02.2011, 12:18  [ТС]     Глупый вопрос по указателям? #3
Извиняюсь, правил код.
Выделенной памяти ведь нет для var2 и будет некорректная работа с памятью?
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
11.02.2011, 12:28     Глупый вопрос по указателям? #4
Ты приводишь объект базового класса к производному от него. В производном классе могут быть какие угодно дополнительные поля, каких не было в базовом классе. Но не факт, что выйдешь за память.
C++
1
new A
выделяет память, достаточную, для хранения экземпляра A, но не всегда размером с экземпляр A. Вот если сразу на массив выделять
C++
1
new A[n]
, тогда уже var1 на соседнем элементе этого массива. Но это относится только к полям, но не к методам, так как методам не нужна память в каждом экземпляре.

Добавлено через 1 минуту
Две последние строки и здесь эквивалентны, в первом случае ты просто сохранил указатель
C++
1
(B*)x
в переменной y, а во втором случае работаешь "с колёс".

Добавлено через 1 минуту
А чего ты вообще хочешь? Зарезервировать память под поля производного класса?
Alex1234
13 / 13 / 0
Регистрация: 11.02.2011
Сообщений: 55
11.02.2011, 12:34  [ТС]     Глупый вопрос по указателям? #5
Спасибо большое! Значит правильно понял. Просто запутался. Давно не имел дела с C++. Не понимаю зачем компиляторы такое допускают.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
11.02.2011, 12:50     Глупый вопрос по указателям? #6
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class B
{
 public:
  int a;
  int b;
  void f1();
  void f2();
};
class C
{
 public:
  int a;
  int b;
  voidb f1();
  void f3();
  void f4();
}
И надо выполнить f4 для экземпляра B, причём, оба объекта по смыслу задачи близки, или совпадают, но тебе для каких то целей понадобились раздельные классы. Например, это могут быть комплексные числа в алгебраической и тригонометрической записи. Количество и типы полей совпадают, за память ты не выйдешь, даже если будешь писать/читать, а методы и операторы-члены могут не совпадать. Вот здесь это и пригодится: оба производные от A, но A может быть вообще абстрактным, тогда нельзя создать экземпляр A. Вешать же защиту бесполезно: преобразуют так:
C++
1
2
3
4
5
B *b;
C *c;
void *d;
d=(void *)b;
c=(C *)d;
. Да и бессмысленна такая защита: если уж берёшься писать что либо кроме программ тестового и учебного назначения, то должен понимать, что пишешь, а иначе всё равно найдёшь где сглючить.
Alex1234
13 / 13 / 0
Регистрация: 11.02.2011
Сообщений: 55
11.02.2011, 20:11  [ТС]     Глупый вопрос по указателям? #7
Спасибо! Думаю, еще может пригодится для альтернативной обработки A[n]. Но лишний раз лучше не использовать.

Добавлено через 50 минут
Посоветуйте, что нибудь почитать понятное про размещение объектов в памяти, с разными случаями: типа смещение указателя при приведение типов в случае с множественным наследованием и т.п. Хочу полностью разобраться.

Добавлено через 6 часов 2 минуты
Добрый вечер! У меня еще вопрос по поводу подобных объявлений A* x = new B;
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class A
{
private:
    virtual void virt(){}
};
 
class B: public A
{
public:
    virtual void virt(){}
    int var[100];
};
 
int main(int argc, char *argv[])
{
    A* x = new B;   //Памяти выделили размером A,  
                    //ссылку на vtable получили от B,
                    //да еще и B::virt на которую ссылается
                    //vtable x стал закрытым, 
                    //т.е. x->virt(); не будет работать.
 
}
Правил что-то много получается. Как A* x = new B интерпретировать мозгом?
silent_1991
Эксперт С++
4961 / 3037 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
11.02.2011, 20:38     Глупый вопрос по указателям? #8
А что интерпретировать-то? Потомок всегда обладает всеми свойствами предка, т.е. членами-данными и методами. Значит его можно легко усечь до предка.
Alex1234
13 / 13 / 0
Регистрация: 11.02.2011
Сообщений: 55
11.02.2011, 22:22  [ТС]     Глупый вопрос по указателям? #9
Спасибо! Разобрался. А то совсем запутался.
C++
1
A* x = new B;
Это тоже самое, что
C++
1
2
    B* z = new B;
    A* x = z;
Усечение до предка, только память на весь B* z = new B; не выделяется.
silent_1991
Эксперт С++
4961 / 3037 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
11.02.2011, 22:26     Глупый вопрос по указателям? #10
Да, по такому усечённому указателю мы сможем обратиться только к членам, которые есть в предке.
Alex1234
13 / 13 / 0
Регистрация: 11.02.2011
Сообщений: 55
12.02.2011, 09:44  [ТС]     Глупый вопрос по указателям? #11
Ой. Обшибся. Память все таки выделяется. Че я так запарился на пустом месте.

Добавлено через 11 часов 8 минут
Здравствуйте! Еще вопрос.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class A
{
public:
    virtual ~A(){}
};
 
class B: public A
{
public:
    int var[100000];
    virtual ~B(){}
};
 
 
int main(int argc, char *argv[])
{
    B* z = new B;
    A* x = z;
 
    delete x;
}
С диструктором разобрался. А память выделенная под z освободится при delete x?
Iron Bug
22 / 22 / 0
Регистрация: 06.12.2010
Сообщений: 125
12.02.2011, 13:04     Глупый вопрос по указателям? #12
Цитата Сообщение от Alex1234 Посмотреть сообщение
С диструктором разобрался. А память выделенная под z освободится при delete x?
нет. и в первом вопросе обращение к члену класса B некорректно.

а вообще, сделай явные конструкторы и деструкторы у твоих классов и пиши оттуда сообщения в консоль, например. тогда сам увидишь, что и где вызывается. это самый простой метод, чтобы не задавать кучу вопросов.
Alex1234
13 / 13 / 0
Регистрация: 11.02.2011
Сообщений: 55
12.02.2011, 20:15  [ТС]     Глупый вопрос по указателям? #13
Что от куда вызывается и так понятно, неоднозначности здесь нет, по этому диструктор виртуальный. Не пойму освободится память выделенная под int var[100000];
Iron Bug
22 / 22 / 0
Регистрация: 06.12.2010
Сообщений: 125
12.02.2011, 21:14     Глупый вопрос по указателям? #14
если спрашиваешь - значит, не понятно.
во-первых, ответ однозначный - нет. во-вторых - напиши деструкторы и сам увидишь, что и где. зачем гадать? или читай Страуструпа, до просветления.
вообще, неясно, зачем такие вывихи устраивать. давно придумали смарт-указатели и все, кто не понимает сути работы с конструкторами-деструкторами, счастливы.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
12.02.2011, 23:09     Глупый вопрос по указателям?
Еще ссылки по теме:

Глупый вопрос про наследование - C++
Вот фрагмент кода, реального: class CListviewParamPrimary : public CListviewParamFloats { private: /** * @brief Возвращает...

Глупый вопрос (возведение в квадрат) - C++
Всем привет. Почему то не работает следующая элементарныя строчка кода. Значения y получаются отрицательными, например около -30000, хотя...

Глупый вопрос по типу данных Variant - C++
Обнаружил, что не очень четко понимаю что он из себя представляет и при его использовании возникает пачка вопросов. Может быть...

Стек, связный список и глупый вопрос - C++
Содержание stack.h #include <cstddef> // Определение константы NULL template <typename T> class Stack { public: Stack(); ...


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

Или воспользуйтесь поиском по форуму:
Напильнег
480 / 120 / 10
Регистрация: 30.09.2010
Сообщений: 473
12.02.2011, 23:09     Глупый вопрос по указателям? #15
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A
...
};
 
class B: public A
...
};
 
int main(int argc, char *argv[])
{
    B* z = new B;
    A* x = z;
 
    delete x;
}
Цитата Сообщение от Alex1234 Посмотреть сообщение
память выделенная под z освободится при delete x?
Память по переменную z типа (B *), выделяется в стеке и автоматически освобождается по достижению конца операторного блока, и delete x ее никак не касается.

Что же до памяти, указателем на которую проинициализирована z, то она по delete x освобождается корректно (т.е. освобождается sizeof(B) байт) с вызовом деструктора B::~B, т.к. для экземпляров потомков класса, имеющего виртуальные методы, размер экземпляра и указатель на деструктор (и вообще на виртуальные методы) берутся из актуальной таблицы ВМТ, по указателю, хранящемся в экземпляре, а не по типу указателя на класс предка, по которому происходит обращение - собственно, для этого механизм виртуальных методов и создавался.
Yandex
Объявления
12.02.2011, 23:09     Глупый вопрос по указателям?
Ответ Создать тему
Опции темы

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