Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Новый класс


Автор: UnixBeginner 5.2.2006, 22:45
у меня нет опыта написания шаблонов и перегрузге операторов, но вот понадобился такой класс - аналог miltiset, только без сортировки:
Код

#ifndef GUARD_list_array_H_INCLUDED
#define GUARD_list_array_H_INCLUDED

#include <iostream>
#include <list>
using namespace std;

template <class T1, class T2>
class list_array
{
    public:
        list_array();
        ~list_array();
        
        class iter
        {
            public:
                iter()
                {
                    iter1 = list1.begin();
                    iter2 = list2.begin();
                    first = *iter1;
                    second = *iter2;
                };
                ~iter();
                
                iter operator++ ()
                {
                    ++iter1;
                    ++iter2;
                    first = *iter1;
                    second = *iter2;
                };
                /*
                iterator operator= (iterator obj)
                {
                    iter1 = obj.iter1;
                    iter2 = obj.iter2;
                };
                */
                T1 first;
                T2 second;
                
            protected:
                list<T1>::iterator iter1; //пишет что после list<T1>::iterator должна быть ;
                list<T2>::iterator iter2;
        };
        
        iter begin()
        {
            iter iter;
            iter.iter1 = list1.begin();
            iter.iter2 = list2.begin();
            
            return  iter;
        }
        
    private:
        list<T1> list1;
        list<T2> list2;
};

#endif //GUARD_list_array_H_INCLUDED



как решить ошибку? Что сделать?

Автор: Daevaorn 5.2.2006, 22:57
UnixBeginner
Попробуй
Код

typename list<T1>::iterator iter1;
typename list<T2>::iterator iter2;

Автор: UnixBeginner 6.2.2006, 10:53
Исправил, теперь вроде ОК, но когда я создаю переменную этого типа:
Код

list_array<double, double> array;

то компановщик выдает ошибку:
Код

[Linker error] undefined reference to `list_array<double, double>::list_array()' 


Что это может быть?

Автор: MAKCim 6.2.2006, 11:03
Цитата

Исправил, теперь вроде ОК, но когда я создаю переменную этого типа:
list_array<double, double> array;
то компановщик выдает ошибку:
[Linker error] undefined reference to `list_array<double, double>::list_array()'

отсутствует тело конструктора и деструктора, надо написать
Код

#include <iostream>
#include <list>
using namespace std;
template <class T1, class T2>
class list_array
{
    public:
[B]        list_array() {}
        ~list_array() {}[/B]
        
        class iter
        {
            public:
                iter()
                {
                    iter1 = list1.begin();
                    iter2 = list2.begin();
                    first = *iter1;
                    second = *iter2;
                };
                ~iter();
                
                iter operator++ ()
                {
                    ++iter1;
                    ++iter2;
                    first = *iter1;
                    second = *iter2;
                };
                /*
                iterator operator= (iterator obj)
                {
                    iter1 = obj.iter1;
                    iter2 = obj.iter2;
                };
                */
                T1 first;
                T2 second;
                
            protected:
                list<T1>::iterator iter1; //пишет что после list<T1>::iterator должна быть ;
                list<T2>::iterator iter2;
        };
        
        iter begin()
        {
            iter iter;
            iter.iter1 = list1.begin();
            iter.iter2 = list2.begin();
            
            return  iter;
        }
        
    private:
        list<T1> list1;
        list<T2> list2;
};
#endif //GUARD_list_array_H_INCLUDED


Автор: UnixBeginner 6.2.2006, 11:06
Вот:
Код

#include "listarray.h"

template <class T1, class T2> 
list_array<T1, T2>::list_array()
{
}

template <class T1, class T2> 
list_array<T1, T2>::~list_array()
{
}

template <class T1, class T2> 
list_array<T1, T2>::iterator::iterator()
{
    iter1 = 0;
    iter2 = 0;
    first = *iter1;
    second = *iter2;
}
template <class T1, class T2> 
list_array<T1, T2>::iterator::~iterator()
{
}

template <class T1, class T2> 
typename list_array<T1, T2>::iterator list_array<T1, T2>::iterator::operator++ ()
{
    ++iter1;
    ++iter2;
    first = *iter1;
    second = *iter2;
}

template <class T1, class T2>
typename list_array<T1, T2>::iterator list_array<T1, T2>::iterator::iterator::operator= (iterator obj)
{
    iter1 = obj.iter1;
    iter2 = obj.iter2;
}
                
template <class T1, class T2> 
typename list_array<T1, T2>::iterator list_array<T1, T2>::begin()
{
    iterator iter;
    iter.iter1 = list1.begin();
    iter.iter2 = list2.begin();

    return  iter;
}

template <class T1, class T2>
void list_array<T1, T2>::value_type(T1 val1, T2 val2)
{
    list1.push_back(val1);
    list2.push_back(val2);
}



Автор: Empirik 6.2.2006, 11:31
Дело в том, что объевление и тело шаблонного метода должны находиться в одном файле, иначе ни как. Это связанно с раздельной компиляцией. Перенеси все в один файл и будет тебе счастье. Или инклудом включай и h файл и cpp файл. Компилятору, что бы инстанцировать шаблонный класс, нужно мразу же иметь и интерфейс класса и тела его методов.

Автор: UnixBeginner 6.2.2006, 11:33
Отлично, все заработало!
Большое спасибо!

Автор: UnixBeginner 6.2.2006, 12:08
Еще вопрос:
Хочу чтобы в данном классе было подобие итератора в STL контейнеров, ну разве только намного проще smile.
Как это можно сделать.
Описал класс iterator в классе list_array (см. выше).

Теперь обращаюсь к нему:
Код

list_array< int, int> array;
list_array< int, int>::iterator iter;
iter = array.begin(); //как описать эту функцию? чтобы присваивались нужные данные? 
//попытка описана выше.

Автор: Earnest 6.2.2006, 21:37
Какой-то странный у тебя контейнер получается... Два параллельных списка? Ну зачем такой изврат, не пойму...
Во первых, лишний расход памяти: каждый узел списка добавляет еще по 2 указателя - зачем этот расход удваивать? Итератор двойной... жуть smile

Опять же, приличный итератор должен разыменовываться в тип элемента, а кто тут у нас элемент? Прямо-таки просится std::pair...

Ну и чем тебя std::list<std::pair<T1,T2> > не устраивает?

Если очень хочется свой тип иметь, то можно так:

Код

template <class T1,class T2>
class pair_list: public std::list<std:pair<T1,T2> >
{
// здесь добавить конструкторов
};

И все...


Автор: UnixBeginner 7.2.2006, 10:38
а ну да, просто этот пункт в книжке я видать пропустил smile про std::pair<>

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