Модераторы: bsa

Поиск:

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


Опытный
**


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

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



bsa
Вродебы сделал чего-то сделал
Класс
Код

class Vector
{
    T* V;
    int n;
    int capacity;
public:
    Vector(int=0);
    Vector(const Vector&);
    int size(){return n;}
    int begin(){return 0;}
    int capacit(){return capacity;}
    int end(){return n;}
    Vector resize(int);
    Vector& erase(int);
    void push_back(T);
    ~Vector(){delete[] V;}
    T& operator[](int i){return V[i];}
};

метод
Код

Vector<T> Vector<T>::resize(int k)
{
    if(capacity>k||k<0) return *this;
    else 
    {
        while(k>capacity)
            capacity*=2;
        Vector buf=*this;
        delete[] V;
        n=k;
        V=new T[capacity];
        for(int i=0;i<capacity;i++)
        if(i<buf.size())(*this)[i]=buf[i];
            else (*this)[i]=0;
    }
    return *this;
}

Изменил конструктор
Код

Vector<T>::Vector(int k)
{
    capacity=1;
    while(k>capacity)
        capacity*=2;
    n=k;
    V=new T[capacity];
}



mes
Ну я уже взялся, тем более я взялся, чтобы понять как работают классы как перекгружать и т.д. 
Да конечно я буду использовать свой вектор тока в лабах, но думаю мне пойдет на пользу если я сделаю грамотно всё.

PM MAIL   Вверх
mes
Дата 2.4.2010, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(ИванМ @  2.4.2010,  16:55 Найти цитируемый пост)
Но думаю в данном случае это избыточная информация. 

А мне показалось, что как раз сейчас самое время показать, как обойти недостатки вектора, и чтоб пришло понимание, что неоптимальность вектора это не вина вектора, а неправильный выбор программистом либо контейнера либо алгоритма использования  smile

Добавлено @ 18:04
Цитата(toxx @  2.4.2010,  17:02 Найти цитируемый пост)
я взялся, чтобы понять как работают классы как перекгружать и т.д. Да конечно я буду использовать свой вектор тока в лабах, но думаю мне пойдет на пользу если я сделаю грамотно всё.

При таком подходе польза обязательно должна быть smile

Добавлено @ 18:09
Цитата(toxx @  2.4.2010,  17:02 Найти цитируемый пост)
    if(capacity>k||k<0) return *this;

изменение типа k на  unsigned .. поможет избавиться от ненужной нагрузки на логику такой как проверка k<0.

Цитата(toxx @  2.4.2010,  17:02 Найти цитируемый пост)
     Vector buf=*this;
        delete[] V;

не очень удачное решение, удалять контейнер, до получения нового..
Логичнее заполнять новый, потом swap`нуть и только после этого удалять ненужное..

Добавлено через 7 минут и 49 секунд
Цитата(toxx @  2.4.2010,  17:02 Найти цитируемый пост)
 for(int i=0;i<capacity;i++)

память находящуюся между size и capacity не нужно занулять.. Это логически лишнее..

Добавлено через 11 минут и 58 секунд
Цитата(toxx @  2.4.2010,  17:02 Найти цитируемый пост)
capacit()

интерфейсные (открытые) методы желательно называть неизменным именем, в отличие от приватных членов, которые не столь придирчивы к измененному написанию.. А в общем для них желательно добавлять аффикс,  для узнаваемости, чтоб не путать с локальными переменными и передаваемыми параметрами..


Это сообщение отредактировал(а) mes - 2.4.2010, 18:09


--------------------
PM MAIL WWW   Вверх
ИванМ
Дата 2.4.2010, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(toxx @  2.4.2010,  18:02 Найти цитируемый пост)
Ну я уже взялся, тем более я взялся, чтобы понять как работают классы как перекгружать и т.д. 
Да конечно я буду использовать свой вектор тока в лабах, но думаю мне пойдет на пользу если я сделаю грамотно всё.

Тогда желаю удачи в своем совершенствовании. Это правильная позиция.
PM MAIL   Вверх
mes
Дата 2.4.2010, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(toxx @  2.4.2010,  17:02 Найти цитируемый пост)
    capacity=1;
    while(k>capacity)
        capacity*=2;

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

Добавлено через 2 минуты и 4 секунды
Цитата(toxx @  2.4.2010,  17:02 Найти цитируемый пост)
  int size(){return n;}
    int begin(){return 0;}
    int capacit(){return capacity;}
    int end(){return n;}

уже упоминал, но еще раз повторю, что тут наиболее удобными будет один из беззнаковых типов.


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


Опытный
**


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

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



mes 
1.Заменил тип(как посоветовал bsa на size_t, чтож попробуем)
Код

size_t capacity;

2.Цикл поправил
Код

for(int i=0;i<n;i++)

3. А вот насчет 
Код

 Vector buf=*this;
        delete[] V; 


не совсем понял почему, тогда придется еще дополнительно мне перегрузить operator=, чтобы уж было красиво.

4.Я не понимаю почему тогда столько книг написано по STL и довольно многие пользуются,
что не глянь тему, люди вашего уровня все переделывают на vector, iterator и пишут,что лучше его использовать(да наверно не везде)...
PM MAIL   Вверх
mes
Дата 2.4.2010, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(toxx @  2.4.2010,  17:26 Найти цитируемый пост)
Я не понимаю почему тогда столько книг написано по STL и довольно многие пользуются,
что не глянь тему, люди вашего уровня все переделывают на vector, iterator и пишут,что лучше его использовать(да наверно не везде)... 

лучше чем самопально написаннный динамический массив, а также он самый простой для понимания, и лучше для тех, кто не сталкивался еще с стл,
в остальных случаях какой из конкейнеров лучше, а может даже какая их связка, зависит от решаемой задачи.
добавлю сразу, что на текущий момент стл не покрывает всех потребностей в контейнерах, но их хватает на основные жизненые случаи.
smile

Добавлено через 1 минуту и 48 секунд
Цитата(toxx @  2.4.2010,  17:26 Найти цитируемый пост)
не совсем понял почему, тогда придется еще дополнительно мне перегрузить operator=, чтобы уж было красиво.

нет, лучше добавить оператор swap , пригодится не только для текущей ситуации...  не бойтесь он очень простой в реализации smile

 


--------------------
PM MAIL WWW   Вверх
toxx
Дата 2.4.2010, 18:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Исправил, пока без swap'a
Код

class Vector
{
    T* V;
    size_t n;
    size_t capacity;
public:
    Vector(int=0);
    Vector(const Vector&);
    size_t size(){return n;}
    size_t begin(){return 0;}
    size_t capacit(){return capacity;}
    size_t end(){return n;}
    Vector resize(int);
    Vector& erase(int);
    void push_back(T);
    ~Vector(){delete[] V;}
    T& operator[](int i){return V[i];}
};

Код

Vector<T> Vector<T>::resize(int k)
{
    if(capacity>k) return *this;
    else 
    {
        capacity=1;
        while(k>capacity)
            capacity*=2;
        Vector buf=*this;
        delete[] V;
        n=k;
        V=new T[capacity];
        for(int i=0;i<n;i++)
        if(i<buf.size())(*this)[i]=buf[i];
            else (*this)[i]=0;
    }
    return *this;
}

и конструктор заодно
Код

Vector<T>::Vector(int k)
{
    capacity=0;
    n=k;
    V=new T[n];
}


Еще + в том, что я сразу могу проверить свой вектор на деле( я с помощью него дерево храню эн-мерное, в соседней теме)

Это сообщение отредактировал(а) toxx - 2.4.2010, 18:38
PM MAIL   Вверх
mes
Дата 2.4.2010, 18:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(toxx @  2.4.2010,  17:36 Найти цитируемый пост)
   capacity=0;
    n=k;

вместимость  не может быть меньше размера..

Добавлено @ 18:56
Цитата(toxx @  2.4.2010,  17:36 Найти цитируемый пост)
    while(k>capacity)
            capacity*=2;

у вас получается, что вместимость всегда равна степени 2ки, а суть не в этом,
а в том чтоб увеличивать текущую вместимость на определенный коэффициент.

кстати хотелось бы также отметить, что коэф. 2 не самый оптимальный, но для простоты пойдет.

Добавлено @ 18:57
В остальном нужно подождать, пока внесете изменения уже озвученные в этой теме..


Это сообщение отредактировал(а) mes - 2.4.2010, 19:01


--------------------
PM MAIL WWW   Вверх
toxx
Дата 2.4.2010, 19:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



ИванМ,mes 
Да... идей вы мне подкинули массу, спасибо.
Как с деревом разберусь еще добавлю идею swap(mes'a).


Это сообщение отредактировал(а) toxx - 2.4.2010, 21:09
PM MAIL   Вверх
toxx
Дата 3.4.2010, 20:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



mes
А скажите пожалуйста основную идею swap?
т.е. как я понял(т.е. не понял) если менять местами векторы Х и Y это чтото типа
Код

void swap(Vector<T>& x,Vector<T>& y);

тогда применительно к чему вызывать этот метод?(я написал свой метод и объявил его другом для класса, походу это не верно...)
Код

friend void swap(Vector,Vector);

вот что получилось(если честно судя по моему забору он не верный...+ он не компилируется)
Код

void swap(Vector<T>& x,Vector<T>& y)
{
    T tmp,size_min,size_max;

    if(x.n>y.n) 
    {
        y.resize(x.n);
        size_min=y.n;
        size_max=x.n;

        for(size_t i=0;i<size_max;i++)
        {
            tmp=x[i];
            x[i]=y[i];
            y[i]=tmp;
        }

        x.resize(size_min);
    }
    else 
    {
        x.resize(y.n);
        size_min=x.n;
        size_max=y.n;

        for(size_t i=0;i<size_max;i++)
        {
            tmp=x[i];
            x[i]=y[i];
            y[i]=tmp;
        }

        y.resize(size_min);
    }
}


Еще есть идея, что он как конструктор копирования вызывается для указателя(это больше похоже на правду)
PM MAIL   Вверх
mes
Дата 3.4.2010, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(toxx @  3.4.2010,  19:05 Найти цитируемый пост)
вот что получилось(если честно судя по моему забору он не верный

все гораздо проще:
Код

class Vector
{
   public:
       void swap ( Vector& rhs ) 
       {
            std::swap ( m_data,  rhs.m_data );
            std::swap ( m_size,  rhs.m_size );
       }
   private:
       T *         m_data;
       size_t      m_size;
};

smile

Это сообщение отредактировал(а) mes - 3.4.2010, 20:23


--------------------
PM MAIL WWW   Вверх
toxx
Дата 3.4.2010, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



mes
оу, до такого ябы не додумался(даже не знал о существовании такого)

Переписал resize() со swap
capacity у меня по степени двойки=)
Код

Vector<T> Vector<T>::resize(size_t k)
{
    if(capacity>k) return *this;
    else 
    {
        capacity=1;
        while(k>capacity)
            capacity*=2;

        Vector<T> buf(k);
        for(size_t i=0;i<buf.size();i++)
            if(i<n)buf[i]=(*this)[i];
                else buf[i]=0;

        delete[] V;
        n=k;
        V=new T[capacity];
        buf.swap(*this);    
    }
}

PM MAIL   Вверх
mes
Дата 3.4.2010, 21:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(toxx @  3.4.2010,  19:56 Найти цитируемый пост)
Переписал resize() со swap

Вы уверены ? попробуйте исправить сами без подсказки ..

Добавлено @ 21:17
Цитата(toxx @  3.4.2010,  19:56 Найти цитируемый пост)
capacity у меня по степени двойки=)

имхо логичней все таки
Код

if  (new_size>capacity) capacity = new_size * 2;




Это сообщение отредактировал(а) mes - 3.4.2010, 21:18


--------------------
PM MAIL WWW   Вверх
toxx
Дата 3.4.2010, 22:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



mes
Интересно, я сначала подумал почему не работает...
потом откомпилировал 5 раз подряд из них 4 раза компилирует и работает, на 5й показывает ошибку доступа к памяти crtexe.c
Код

template <class T>
Vector<T> Vector<T>::resize(size_t new_size)
{
    if(capacity>new_size) return *this;
    else 
    {
        Vector buf(new_size);
        if(new_size>capacity)
            capacity=new_size*2;

        for(size_t i=0;i<n;i++)
            buf[i]=(*this)[i];

        delete[] V;
        n=new_size;
        V=new T[capacity];
        buf.swap(*this);
    }
}


Это сообщение отредактировал(а) toxx - 3.4.2010, 22:25
PM MAIL   Вверх
mes
Дата 3.4.2010, 22:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


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

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



Цитата(toxx @  3.4.2010,  21:09 Найти цитируемый пост)
Vector<T> Vector<T>::resize(size_t new_size)

вообще-то resize() возвращает void 
ну а ошибки не все исправили ..


Это сообщение отредактировал(а) mes - 3.4.2010, 22:30


--------------------
PM MAIL WWW   Вверх
Страницы: (5) Все 1 2 [3] 4 5 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




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


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

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