Погода: -12°C
  • Есть класс Base, от которого наследуются классы Child1, Child2, Child3. Пусть экземпляры дочерних классов описывают свойства айтемов какого-то меню, которые как-то выбираются пользователем.

    Вопрос.
    Что происходит с памятью в случае нижеприведенной реализации?

    // ----------------------

    void main(void)
    {
    Base *obj;

    ...

    switch(int i)
    {
    case 1: obj = new Child1; break;
    case 2: obj = new Child2; break;
    case 3: obj = new Child3; break;
    }
    obj->show();
    }

    // ---------------------

    Каким образом выделяется память под объекты, определяемые пользователем? Грубо говоря, если
    передать в наш switch() последовательно 1, 2, 3, 2, 1, 2 или что-нить в этом роде, выделится память для всех объектов или же каждый раз объект будет переписываться в память начиная с позиции, на которую указвыает *obj?

  • Каждый раз натыкаясь на new программа будет создавать новый обьект указанного класса, переопределяя значение указателя obj. По-моему так.

    Землю - крестьянам, фазу - электрикам!!

  • Выделится память для всех объектов, но доступ будет только к последнему, а остальные будут болтаться в динамической памяти мусором. Самый простой выход - использовать массив указателей.

    Осторожнее с травой!
    Если хапнешь много дряни
    Увезут тебя с собой
    Злые инопланетяне

  • А ещё можно создать просто статическое меню. (не путать с заболеванием) :спок:

    Землю - крестьянам, фазу - электрикам!!

  • Думаю, что если бы человека устраивало статическое, то он не парился бы с динамическим....:улыб:

    Когда проснулся, тогда и "Доброе утро!"

  • если
    передать в наш switch() последовательно 1, 2, 3, 2, 1, 2 или что-нить в этом роде, выделится память для всех объектов или же каждый раз объект будет переписываться в память начиная с позиции, на которую указвыает *obj?

    Объекты будут каждый раз создаваться заново, а значение obj меняться. Чтобы не было утечек памяти (не Java все-таки), лучше написать что-то вроде:

    void main(void)
    {
    Base *obj = NULL;

    ...

    Child1 *child1 = NULL;
    Child2 *child2 = NULL;
    Child3 *child3 = NULL;

    switch(i)
    {
    case 1:
    if (!child1) child1 = new Child1;
    obj = child1;
    break;

    case 2:
    if (!child2) child2 = new Child2;
    obj = child2;
    break;

    case 3:
    if (!child3) child3 = new Child3;
    obj = child3;
    break;
    }

    if (obj) obj->show();

    delete child1;
    delete child2;
    delete child3;
    ....

    }

    Тогда экземпляры menuitem'ов не будут дублироваться и не будут теряться ссылки на них.

    who | grep -i blonde | date; cd ~; unzip; touch;
    strip; finger; mount; gasp; yes; uptime; umount;

  • Мертвая птица тебе поможет.
    На сколько я помню, там достаточно хорошо описано что делает new и почему после него нужно делать delete, зачем нужны виртуальные диструкторы и т.д.

    Toyota Vitz 2005 1.3-> Mercedes CLK 2002 2.3 Kompressor-> Kia Sportage 2012 Biturbo T-GDI

  • В ответ на: Объекты будут каждый раз создаваться заново, а значение obj меняться. Чтобы не было утечек памяти (не Java все-таки), лучше написать что-то вроде:
    ......
    Давно не трогал с++, помоему там проще сделать у наследников виртуальный диструктор и код тогда будет типа такого

    void main(void)
    {
    Base *obj = NULL;

    ...


    switch(i)
    {
    case 1:
    obj = new child1;
    break;

    case 2:
    obj = new child2;
    break;

    case 3:
    obj = new child3;
    break;
    }

    if (obj) obj->show();

    delete obj;
    ....

    }

    Toyota Vitz 2005 1.3-> Mercedes CLK 2002 2.3 Kompressor-> Kia Sportage 2012 Biturbo T-GDI

    Исправлено пользователем Egor_M (19.10.04 21:19)

  • помоему там еще у всех наследников должен быть виртуальный диструктор.
    Ессно.

    who | grep -i blonde | date; cd ~; unzip; touch;
    strip; finger; mount; gasp; yes; uptime; umount;

  • поздно уже, не внимательно прочитал код.
    исправил пост.

    зачем там городить огороды с 3-мя указателями, если достаточно 1 -го указателя на Base и виртуальных деструкторов в потомках.

    Toyota Vitz 2005 1.3-> Mercedes CLK 2002 2.3 Kompressor-> Kia Sportage 2012 Biturbo T-GDI

  • зачем там городить огороды с 3-мя указателями, если достаточно 1 -го указателя на Base и виртуальных деструкторов в потомках.
    Ну, код там вообще сам по себе странный, задумка автора слишком не ясна, но можно, конечно, добавить всего одну строку после вызова ->show():

    delete obj;

    чтобы удалять использованный экземпляр объекта.

    who | grep -i blonde | date; cd ~; unzip; touch;
    strip; finger; mount; gasp; yes; uptime; umount;

  • Та-ак.. вроде кое-что начинает проясняться.
    Только вот виртуальный деструктор - это что?
    Тот самый delete obj, выполняющийся по завершении работы функции?

    А если у меня этих функций много? Более того, приложение виндовое, и в нем присутствует необходимость использования свойств объекта (одного из Child'ов) при нажатии на кнопку.
    Грубо говоря, нажал одну кнопку - пускается одна функция объекта, вторую - другая.

    То есть delete памяти под объект представляется возможным сделать только в момент выделения памяти под другой (при выборе очередного айтема пользователем).

    Разумно ли нижеследующее?

    void main(void)
    {
    Base *obj = NULL;

    ...

    switch(int i)
    {
    delete obj; // пользуемся тем, что указатель остается
    case 1: obj = new Child1; break;
    case 2: obj = new Child2; break;
    case 3: obj = new Child3; break;
    }

    obj->show();
    }

    А мертвая птица - она что-то пока мне кажется пособием для каких-то иноземных существ.

  • В ответ на: delete obj; // пользуемся тем, что указатель остается
    case 1: obj = new Child1; break;
    case 2: obj = new Child2; break;
    case 3: obj = new Child3; break;
    Неа не правильно...
    Как же указатель у тебя остался, если ты в начале функции присвоил его равным NULL? Да и потом obj - это локальная переменная.
    Еще раз повторю: используй массив указателей, это проще всего.

    Осторожнее с травой!
    Если хапнешь много дряни
    Увезут тебя с собой
    Злые инопланетяне

  • А как это будет выглядеть?
    Указатель для каждого из Child'ов?

  • Ну примерно так:
    void main(void)
    {
    int i;
    Base *obj[3] ={ NULL,NULL,NULL);

    ...

    switch(i)
    {
    case 1: obj[i] = new Child1; break;
    case 2: obj[i] = new Child2; break;
    case 3: obj[i] = new Child3; break;
    }
    //какие-то действия
    obj[i]->show();
    delete obj[i];
    }
    Или что-то похожее...

    Осторожнее с травой!
    Если хапнешь много дряни
    Увезут тебя с собой
    Злые инопланетяне

  • 1. В предложенном Вами варианте придется делать нечто вроде obj[0]->show();
    Узнать, каким вышел объект из свитча можно только, таская за ним какое-то int'овое значение значение (определяемое, кстати, в том же свитче) для использования в виде
    obj[ i ]->show();
    Но проблема в том, что я могу делать delete только на этапе выделения памяти для другого объекта.

    2. Такой еще вопрос.
    В чем разница между
    Base *obj[3] ={ NULL,NULL,NULL };
    и
    Base *obj[3];

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

  • Определения не идентичны, во втором случае может быть любое значение, т.к. просто резервируется память в стеке.
    В принципе массив можно стделать динамическим или вобще вектором, а память освобождать в кнце программы.

    Осторожнее с травой!
    Если хапнешь много дряни
    Увезут тебя с собой
    Злые инопланетяне

  • В ответ на: А мертвая птица - она что-то пока мне кажется пособием для каких-то иноземных существ.
    Книга такая,
    Страуструп, Язык С++ , я читал 3-е издание, там все было достаточно понятно описано.

    Диструктор - функция такая, которая вызывается при уничтожении объекта.

    Если диструктор не виртуальный то для того, что бы код
    Base *a=new Child1 ;
    delete a;
    отрабатывал коректно, т.е. уничтожел в памяти именно объект класса Child1 а не объект класса Base для каждого наследника нужно переопределять оператор delete, что выглядит убого, проще создать пусть даже пустой виртуальный диструктор.


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

    Ответы нв вопросы: что такое диструктор? что такое виртуальная функция? и подобные ты найдешь практически в любой книге по С++.

    Toyota Vitz 2005 1.3-> Mercedes CLK 2002 2.3 Kompressor-> Kia Sportage 2012 Biturbo T-GDI

  • В ответ на: Еще раз повторю: используй массив указателей, это проще всего.
    Просто напомнило мне рассказ моего друга как он сдавал программирование на паскале в универе.
    Тема была указатели, когда он сдавал прогу , препод(женщина) спросила указывая на какую-то переменную, что это такое. Он ответил, что это массив указателей.
    После этого ответа она была в замешательстве секунд 30, и потом сразу поставила ему 5.
    Видимо ей самой тяжело далось понятие указателя, а их массив просто повер ее в шок.

    Toyota Vitz 2005 1.3-> Mercedes CLK 2002 2.3 Kompressor-> Kia Sportage 2012 Biturbo T-GDI

  • И все-таки действительно ли так необходимо динамическое меню. Ведь пункт меню должен создаваться (дополняться ) один раз и, соответственно ВСЕ динамическое меню должно быть delete перед завершением программы . Способ активно/неактивно отображаемо/неотображаемо неприемлем?

    Землю - крестьянам, фазу - электрикам!!

  • Помню как-то я сдавал программирование в Универе, так я зафигачил двусвязный список матриц на Паскале....:улыб:
    Препод тоже была женщина. И тоже поставила 5, хотя теорию я ей завалил на откровенную пару :ха-ха!:

    Когда проснулся, тогда и "Доброе утро!"

  • В ответ на: И все-таки действительно ли так необходимо динамическое меню. Ведь пункт меню должен создаваться (дополняться ) один раз и, соответственно ВСЕ динамическое меню должно быть delete перед завершением программы . Способ активно/неактивно отображаемо/неотображаемо неприемлем?
    Неа. Просто много пунктов меню, и в таком случае уж слишком много памяти используется.

  • В ответ на: Блин, ты бы почитал литературу хоть немного, нафига сразу в форум переть с такими вопросами.

    Ответы нв вопросы: что такое диструктор? что такое виртуальная функция? и подобные ты найдешь практически в любой книге по С++.
    Я вполне знаком с упомянутыми понятиями, просто они не в достаточной мере мной "прощупаны" на практике до уровня решения вот, например, такой задачи, какая приведена здесь.

    Несовершенность своих знаний мне очевидна не меньше Вашего, и пришел я не за готовым кодом, а за советом.

    Не все рождаются гуру, опыт приходит со временем.

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

  • В ответ на: Я вполне знаком с упомянутыми понятиями, просто они не в достаточной мере мной "прощупаны" на практике до уровня решения вот, например, такой задачи, какая приведена здесь.
    Зря ты пропустил главы о динамическом выделении памяти. А если и пропустил, при решении ЛЮБОЙ задачи правильный подход сначала почитать про это в книгах, почитать документацию, потом уже лезть в форумы с вопросами, если что-то из прочитаного не понятно или ты поискав не нашел ответа на свой вопрос...

    Вот из MSDN:


    When new is used to allocate memory for a C++ class object, the object's constructor is called after the memory is allocated.

    Use the delete operator to deallocate the memory allocated with the new operator.

    Toyota Vitz 2005 1.3-> Mercedes CLK 2002 2.3 Kompressor-> Kia Sportage 2012 Biturbo T-GDI

  • >Диструктор - функция такая, которая вызывается
    >при уничтожении объекта.

    Никаких "диструкторов" у трупа страуса нет ;-))

    Исправлено пользователем Lisper (23.10.04 08:51)

  • Разве не видите, что с этим примером что-то не так. Проблема возникла от того, что в нормальном коде такого быть не должно.

    Исправлено пользователем Lisper (23.10.04 09:14)

  • В ответ на: Никаких "диструкторов" у трупа страуса нет ;-))
    Хорошо, по русскому мне 2:)

    Но "деструкторов" там дофига....

    Toyota Vitz 2005 1.3-> Mercedes CLK 2002 2.3 Kompressor-> Kia Sportage 2012 Biturbo T-GDI

    Исправлено пользователем Egor_M (23.10.04 15:07)

Записей на странице:

Перейти в форум

Модератор: