Поиск:

Ответ в темуСоздание новой темы Создание опроса
> контейнер типа list, контейнер типа list указателей на объект 
V
    Опции темы
N20
Дата 5.1.2012, 02:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 5.1.2012

Репутация: нет
Всего: нет



Доброго времени суток. Помогите пожалуйста с такой задачей. Нужно создать контейнер типа лист в котором будут храниться указатели на объекты моего класса. Организовать добавление и вывод их на экран. Я столкнулся с проблемой, что при использовании данного кода во все объекты, начиная со ВТОРОГО, сохраняется одна и та же информация, при чем та что вводилась мною для последнего объекта. Пожалуйста, объясните почему так происходит, и помогите это исправить. Заранее благодарен.
Код

   int tmp=4;
   list<mr_string*> lst1;
   list<mr_string*>::iterator p;
   lst1.push_back(&mr_string());
    p = lst1.begin();
   (*p)->vvod();
   for(int i=0;i<(tmp);i++)
   {
      lst1.push_back(&mr_string());
      ++p;
      (*p)->vvod();
    }  
   p = lst1.begin();
   cout<< "konteyner nomer 1"<< endl;

   while (p!=lst1.end())
   {
      (*p)->vuvod();
      ++p;
   }

PM MAIL   Вверх
Cheloveck
Дата 5.1.2012, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: нет
Всего: 32



Функция mr_string() возвращает объект в стеке, ты берёшь его адрес и пихаешь в лист. Естественно, что стек затерается. Для хранения списка указателей на объекты нужно хранить также и сами объекты, а ты их теряешь.


--------------------
user posted image
PM Jabber   Вверх
Cheloveck
Дата 5.1.2012, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

Репутация: нет
Всего: 32



Код

#include <iostream>
#include <string>
#include <list>
#include <algorithm>
#include <memory>

class MyObject {
public:
    void Scan() {
        std::cin >> value;
    }

    void Print() const {
        std::cout << value;
    }

private:
    std::string value;
};

MyObject ** MakeBuffer(size_t size) {
    MyObject ** buffer = new MyObject * [size];
    ::memset(buffer, 0, sizeof(MyObject *) * size);
    return buffer;
}

void DropBuffer(MyObject ** buffer, size_t size) {
    std::for_each(&buffer[0], &buffer[size - 1], [](MyObject * obj) { 
        delete obj;
    });
    delete [] buffer;
}

int main() {
    const size_t size = 4;
    MyObject ** buffer = MakeBuffer(size);
    std::list<MyObject *> objects;

    for(size_t i = 0; i < size; ++i) {
        MyObject * obj = new MyObject();
        std::cout << "Type value for object number " << i << ": ";
        obj->Scan();
        buffer[i] = obj;
        objects.push_back(obj);
    }

    std::for_each(objects.begin(), objects.end(), [](MyObject * obj) { 
        obj->Print();
        std::cout << std::endl;
    });

    DropBuffer(buffer, size);

    ::system("PAUSE");
    return 0;
}

Как-то так. Лямбды и for_each можно заменить на старый добрый for по итераторам, если юзаешь C++ отличный от прошлогоднего стандарта.

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

#include <iostream>
#include <string>
#include <list>
#include <algorithm>

class MyObject {
public:
    void Scan() {
        std::cin >> value;
    }

    void Print() const {
        std::cout << value;
    }

private:
    std::string value;
};


int main() {
    const size_t size = 4;
    std::list<MyObject *> objects;

    for(size_t i = 0; i < size; ++i) {
        MyObject * obj = new MyObject();
        std::cout << "Type value for object number " << i << ": ";
        obj->Scan();
        objects.push_back(obj);
    }

    std::for_each(objects.begin(), objects.end(), [](MyObject * obj) { 
        obj->Print();
        std::cout << std::endl;
    });

    std::for_each(objects.begin(), objects.end(), [](MyObject * obj) { 
        delete obj;
    });

    ::system("PAUSE");
    return 0;
}


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

#include <iostream>
#include <string>
#include <list>

class MyObject {
public:
    void Scan() {
        std::cin >> value;
    }

    void Print() const {
        std::cout << value;
    }

private:
    std::string value;
};


int main() {
    const size_t size = 4;
    std::list<MyObject *> objects;

    for(size_t i = 0; i < size; ++i) {
        MyObject * obj = new MyObject();
        std::cout << "Type value for object number " << i << ": ";
        obj->Scan();
        objects.push_back(obj);
    }

    for(std::list<MyObject *>::const_iterator it = objects.begin();
        objects.end() != it; ++it) {
            (*it)->Print();
            std::cout << std::endl;
    }

    for(std::list<MyObject *>::const_iterator it = objects.begin();
        objects.end() != it; ++it) {
            delete (*it);
    }

    ::system("PAUSE");
    return 0;
}


Если между последними двумя циклами ничего делать не нужно, их можно объединить.

Это сообщение отредактировал(а) Cheloveck - 5.1.2012, 17:37


--------------------
user posted image
PM Jabber   Вверх
N20
Дата 5.1.2012, 18:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 5.1.2012

Репутация: нет
Всего: нет



Спасбо большое, очень помогли.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0454 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.