Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Центр помощи > [C++] STL и свои типы данных


Автор: cupper 19.4.2007, 15:00
Вобщем поробую выложить кратко суть проблемы: мне нуно использовать шаблон List со своим типом данных, а я незнаю че нужно переопределять и как ваще ето все замутить. Как работать в STL с стандартыми типами данных немного разбрался.  
Вот есть к примеру *.h файл с моим классом
Код

class hist_event
{
    int year;
    char *even;
public:
    hist_event(); // конструктор по умолчанию
    ~hist_event(){delete []even;}
    int get_year() const {return year;}// метод возвращающий year
    char* get_event() const {return even;}// метод возвращающий  event
    void vvod();// метод обеспечивающий ввод исторического события
    void vivod() const;// метод обеспечивающий вывод исторического события
    hist_event(const hist_event &A);//конструктор копирования
    bool operator > (hist_event & A);// сравнивает по полю year 
    hist_event operator = (const hist_event &A); // переопределенный констуктор присваивания
    friend int interval(hist_event* A, int n);// метод подсчета среднего интервала между историческими событиями
};

все методы этом класе реализованы и протестированы. Кстати если че то они реализованы для обычного использование, не для STL или нет разници. . Нужноли чтонибуть еще сюда или может чтото убрать ваще надо???.
Вот на что меня хватило
Код

#include <iostream>
#include <list>
#include <conio.h>
#include "head.h"
using namespace std;

void out (const List<hist_event> &L){
     copy(L.begin(), L.end(), ostream_iterator<hist_event>(cout," ")); //тут жалуеться 
//и говорит  мол незнаю, не хочу и т.п. про ostream_iterator<hist_event>(cout," ")
     cout<<endl;
}
int main(){
    list <hist_event> L;
    hist_event a;
int i=0;
while (i!=3){
a.vvod();    
L.push_back(a);
i++;
}
    // а вот как вывести все ето я хз
    getch();
}

И вообще хоть штото сдесь есть правильное или я может ваще все неправильно понялsmile .

P.S. если у кого есть простые реализованные примеры по моему вопросу дайте плиз, мне на примерах легче понять чем в книжке.

Автор: boriska 19.4.2007, 15:36
Цитата

copy(L.begin(), L.end(), ostream_iterator<hist_event>(cout," "));    //тут жалуеться.................... 


перегрузи operator<<

Автор: Daevaorn 19.4.2007, 15:37
Ну для начала нужно подключить заголовок <iterator>.  И перегрузить оператор выведения в поток, что-то типа того:
Код

 ostream& operator<<( ostream&, const hist_event& );

Автор: EnergoHokum 20.4.2007, 12:47
Нужно перегрузить: конструктор по умолчанию, конструктор копий, если будет, то конструктор с параметрами, определить виртуальный деструктор, перегрузить оператор присваивания. Дальше - зависит от того, что ты планируешь делать со своим классом, арифметические операторы, operator >>, operator << ну и далее по вкусу. Для твоего класса приблизительно так:
Код

public:
hist_event() : year(0),even(0) {}
hist_event(int newYear,char* newEven) : year(newYear),even(newEven) {}
//с конструктором копий и оператором присваивания сложнее,
//у тебя ведь указатель есть, сам понимаешь, два указателя на один объект - не гут,
//как вариант, можно разместить их в private (запретить), обнулять указатели,
//или удалять копируемый объект. Сделаю второе:
hist_event(const hist_event& he) {year=he.year; even=0;}
hist_even& operator =(const hist_even& he)
{
  if(this == &he)
    return this;//защита от присваивания себя себе
  else
  {
    year=he.year;
    even=0;
  }
return this;
}
friend ostream& operator <<(ostream& os,hist_event he)
{
  os<<"Year is "<<he.year<<endl;
  //как вывести even - непонятно, что оно у тебя значит, это указатель на строку?
  return os;
}

А вообще почитай Элджера, C++ для профессионалов, там и не такое описано.
Для использования в STL ничего специального делать не нужно.

Автор: Daevaorn 20.4.2007, 13:11
Цитата(EnergoHokum @  20.4.2007,  13:47 Найти цитируемый пост)
Нужно перегрузить: конструктор по умолчанию, конструктор копий, если будет, то конструктор с параметрами, определить виртуальный деструктор, перегрузить оператор присваивания. Дальше - зависит от того, что ты планируешь делать со своим классом, арифметические операторы, operator >>, operator << ну и далее по вкусу

Цитата(EnergoHokum @  20.4.2007,  13:47 Найти цитируемый пост)
Для использования в STL ничего специального делать не нужно.

забавно

Автор: HappyLife 20.4.2007, 13:24
Цитата(Daevaorn @ 19.4.2007,  15:37)
Ну для начала нужно подключить заголовок <iterator>.  И перегрузить оператор выведения в поток, что-то типа того:
Код

 ostream& operator<<( ostream&, const hist_event& );

Хех, на мой взгляд проще в классе сделать функтор.
InStream(ostream& stream);

Автор: Daevaorn 20.4.2007, 13:46
Цитата(HappyLife @  20.4.2007,  14:24 Найти цитируемый пост)
Хех, на мой взгляд проще в классе сделать функтор.InStream(ostream& stream);

и что?smile

Автор: HappyLife 20.4.2007, 15:14
Daevaorn, 
да так) Личный опыт. smile Это ни к тебе, ты лишь показал как, я к автору, что перегружать что-то стандартное лишний гемор.

Автор: Daevaorn 20.4.2007, 16:09
Цитата(HappyLife @  20.4.2007,  16:14 Найти цитируемый пост)
да так) Личный опыт.  Это ни к тебе, ты лишь показал как, я к автору, что перегружать что-то стандартное лишний гемор.

а как тогда с std::copy и std::ostream_iterator использовать? вопрос то был именно в этом

Автор: JackYF 20.4.2007, 16:21
Цитата(HappyLife @  20.4.2007,  15:14 Найти цитируемый пост)
перегружать что-то стандартное лишний гемор.

лучше писать нестандартные функторы с нестандартными именами?.. (имхо)

Автор: Earnest 20.4.2007, 20:51
cupper, 

Я правильно понимаю, что в классе hist_event выделяется динамическая память для even, а потом, в деструкторе, уничтожается?
Если так, то тебя ждут увлекательные приключения при использовании контейнеров STL.
Объекты, которые можно класть в контейнеры STL, дожны непременно обладать одним свойством: быть copy-constructable.  
Потому что копирование там на каждом шагу - да хоть взять push_back.
А твой объект таковым не является. И самое печальное, что компилятор сгенерирует тебе конструктор копирования без звука... Он просто скопирует твой указатель... Дальше надо?

А вы беспокоитесь о выводе в поток... Да он просто может не дожить...



Автор: cupper 24.4.2007, 10:36
Цитата(EnergoHokum @ 20.4.2007,  12:47)
Нужно перегрузить: конструктор по умолчанию, конструктор копий, если будет, то конструктор с параметрами, определить виртуальный деструктор, перегрузить оператор присваивания. Дальше - зависит от того, что ты планируешь делать со своим классом, арифметические операторы, operator >>, operator << ну и далее по вкусу. Для твоего класса приблизительно так:
Код

public:
hist_event() : year(0),even(0) {}
hist_event(int newYear,char* newEven) : year(newYear),even(newEven) {}
//с конструктором копий и оператором присваивания сложнее,
//у тебя ведь указатель есть, сам понимаешь, два указателя на один объект - не гут,
//как вариант, можно разместить их в private (запретить), обнулять указатели,
//или удалять копируемый объект. Сделаю второе:
hist_event(const hist_event& he) {year=he.year; even=0;}
hist_even& operator =(const hist_even& he)
{
  if(this == &he)
    return this;//защита от присваивания себя себе
  else
  {
    year=he.year;
    even=0;
  }
return this;
}
friend ostream& operator <<(ostream& os,hist_event he)
{
  os<<"Year is "<<he.year<<endl;
  //как вывести even - непонятно, что оно у тебя значит, это указатель на строку?
  return os;
}


Если меня не подводит память то конструктор по умолчанию, конструктор копирования и конструктор присваивания у мну есть:
Код

class hist_event
{
    ...
public:
    hist_event(); // конструктор по умолчанию
    ~hist_event(){delete []even;}
    int get_year() const {return year;}// метод возвращающий year
    char* get_event() const {return even;}// метод возвращающий  event
    void vvod();// метод обеспечивающий ввод исторического события
    void vivod() const;// метод обеспечивающий вывод исторического события
    hist_event(const hist_event &A);//конструктор копирования
    bool operator > (hist_event & A);// сравнивает по полю year 
    hist_event operator = (const hist_event &A); // переопределенный констуктор присваивания
    friend int interval(hist_event* A, int n);// метод подсчета среднего интервала между историческими событиями
};

Еще раз повторю все ети методы реализованы и протестированы!!!!!!!
Код

friend ostream& operator <<(ostream& os,hist_event he)
{
  os<<"Year is "<<he.year<<endl;
  //как вывести even - непонятно, что оно у тебя значит, это указатель на строку?
  return os; ДА ЭТО УКАЗАТЕЛЬ НА СТРОКУ, так как его вывести блин!!!!*????
}


Добавлено через 14 минут и 26 секунд
Цитата

Я правильно понимаю, что в классе hist_event выделяется динамическая память для even, а потом, в деструкторе, уничтожается?

ДА!!!!!! есть указатель char* ... и в деструкторе она удалаяться!!!
Цитата

Если так, то тебя ждут увлекательные приключения при использовании контейнеров STL.

Если я неошибаюсь то STL есть возмоность использовать свой тип данных, а раз есть возможность то нечего сверХ необычного недолжн быть
Цитата

Объекты, которые можно класть в контейнеры STL, дожны непременно обладать одним свойством: быть copy-constructable.  
Потому что копирование там на каждом шагу - да хоть взять push_back.

ДА Я ПЕРЕОПРЕДЕЛИЛ КОНСТРУКТОР КОПИРОВАНИЯ, ОН РАБОТАЕТ!!!!!!
Цитата

А твой объект таковым не является. И самое печальное, что компилятор сгенерирует тебе конструктор копирования без звука... Он просто скопирует твой указатель... Дальше надо?

Код

hist_event::hist_event(const hist_event &A
    even=new char[strlen(A.even)+1];
                even[0]='\0';
    strcpy(even, A.even);
}



ПОПРОБУЮ перефразировать свою просьбу:
с учетом того что уменя уже реализовано, мне нуно 
1) чтобы я мог кроме того как ввести свой список, так же мог его вывести
2) отсортировать по возростанию
3) имел возможность добавлять элементы
4) умел полностью очистить весь список
4) и еще один мотод который позволял бы находить  средный интервал в годах между событиями 

Автор: Earnest 24.4.2007, 19:24
Цитата(cupper @  24.4.2007,  11:36 Найти цитируемый пост)
ДА Я ПЕРЕОПРЕДЕЛИЛ КОНСТРУКТОР КОПИРОВАНИЯ, ОН РАБОТАЕТ!!!!!!

Извини, твой код особо не смотрела. Ясно, что корректных (в смысле безопасности) вариантов копирования только 2: глубокое копирование и подсчет ссылок. Первый вариант несколько избыточен - выделять память, чтобы немного подвигать элементы, и потом тут же удалить - это как-то... нерентабельно, что ли. Но дело вкуса. И работать будет, если не очень критична производительность. Второй вариант неудобно реализовывать с "голым" указателем. Для этого есть смарт-пойнтеры. Что и рекомендую.

Цитата(cupper @  24.4.2007,  11:36 Найти цитируемый пост)
Если я неошибаюсь то STL есть возмоность использовать свой тип данных, а раз есть возможность то нечего сверХ необычного недолжн быть

Только copy-constructable. Причем корректность копирования полностью на твоей совести. Использование STL все-таки предполагает некоторое понимание процесса, как и C++ в целом. И вообще, С++ - это язык, где зад программисту не подтирают: предполагается, что он уже научился это делать сам.
Извините за грубость, но иногда достает ...

Добавлено через 7 минут и 32 секунды
Цитата(cupper @  19.4.2007,  16:00 Найти цитируемый пост)
hist_event operator = (const hist_event &A); // переопределенный констуктор присваивания

Не бывает. Бывает конструктор копирования (у тебя тоже есть). А это оператор присваивания.
Просто терминология, но тем не менее  smile

Добавлено через 8 минут и 42 секунды
И еще, "правильный" оператор присваивания должен возвращать ссылку, а не копию.

Автор: cupper 25.4.2007, 09:51
Код

hist_event hist_event::operator =(const hist_event &A){
    //if (&A==this) return *this;
    //hist_event even=A.even;
    even=new char [strlen(A.even)+1];
    even[0]='\0';
    strcpy(even,A.even);
    year=A.year;
    return *this;
}



Люди, это программа моя курсовая которую нада сдавать через пол месяца, ведет ее у меня мой декан, пробиться к ней мне не получаеться уже чутли не месяц, так что она мне толком помочь не можетю. ВЫ последняя надежда для меня, я С++ знаю на уровне базового изучения smile , мне нужното всего нечего
Цитата

мне нуно 
1) чтобы я мог кроме того как ввести свой список, так же мог его вывести
2) отсортировать по возростанию
3) имел возможность добавлять элементы
4) умел полностью очистить весь список
5) и еще один мотод который позволял бы находить  средный интервал в годах между событиями  

ПОМОГИТЕ ХОТЬ В ЧЕМТО , и пожалуйста не на словах, а если мона хотябы небольшие но конкретные примеры как это сделать  smile  smile  smile 

Автор: cupper 26.4.2007, 14:16
всем большое спасибо (((((((( :'(

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)