Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 16.11.2011, 00:05   #1
rivett
Новичок
Джуниор
 
Регистрация: 15.11.2011
Сообщений: 2
Плохо с++. контейнеры. не могу понять прогу.

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

Код:
#include "stdafx.h"
#include <iostream>
#include "conio.h"
#include <exception>
 
using namespace std;
 
template < class Object > // шаброн; class object - параметр шаблона? 
class vector // клас вектор. 
{
public:
        explicit vector(int initSize = 0): theSize(initSize),// explicit следует писать для всех конструкторов с одним параметром( а для чего?). т.е. мы объявили конструктор vector; theSize(initSize) - функция кол-ва элементов, а theCapacity(initSize) - вместимость 
                theCapacity(initSize) //  или theSize и theCapacity тож конструкторы???
        {objects = new Object[theCapacity];}// создаем объект с вместимостью theCapacity?
        vector(const vector &rhs):(NULL) // что значит двоеточие после ()? и почему const vector и зачем &rhs
        {operator = (rhs);}// ?
        ~vector()// деструктор 
        {delete [] objects;}
bool empty( ) const  // это функция ?
      { return size( ) == 0; }
Object  &  operator [] (int index) // а это что?
{
        #ifndef NO_CHECK // директива проверки выхода из области вектора?
        if( index < 0 || index >= size())
                throw ArrayIndexOutOfBoundException();// trow - устанавливает тип выбрасываемых исключений?
        #endif
        return objects[index];
}
        const vector & operator = ( const vector &rhs);//перегрузка =?
        void resize (int newSize); // ф-я изменения размера вектора(меняет на newSize)
        void  reserve(int newCapacity); // изменяет вместимость вектора
        void  push_back(const Object &x);// вставка в конец
        int size()const{return theSize;}// размер вектора? почему сonst?
        int capacity()const{ return theCapacity;}// тот же вопрос. при чем тут const
    const Object & back( ) const;//что это
        void pop_back( );// удаление с конца
        private:
                int theSize;
                int theCapacity;
                Object * objects;// что это?
 
};
template <class Object>
const vector<Object>&// зачем & ? это же ,bn равный нулю?
vector<Object>::operator =(const vector<Object>&rhs)
{
        if(this != & rhs)// ?
        
                {
                        delete [] objects; // что мы удаляем?
                        theSize = rhs.size();// новый размер
                        theCapacity = rhs.capacity();//новая вместимость
                        object = new Object[capacity()];// новый  вектор
                        for( int k = 0; k < size();k++)// заполняем вектор?
                                objects[k]=rhs.objects[k];
                }
                return *this;// что мы возвращаем?
}
template <class Object>
void vector <Object>::push_back(const Object& x)// вставляем элемент в конец
{
        if(theSize == theCapacity)// если размер равен вместимости
                reserve(2*theCapacity+1);// увеличиваем вместимость (в два раза +1?)
        objects[ theSize++] = x;// записываем на след-е место наш элемент?
}
template <class Object>
void vector <Object>::reserve(int newCapacity)// изменение вместимости
{
        Object *oldArray = objects;// что мы делаем?
        int numToCopy = newCapacity<theSize?newCapacity:theSize;// вообще не понятна эта строка; numToCopy - что в этой переменной. 
        objects =  new Object[newCapacity];// в старый объект присваиваем новый с новой вместимостью?
        for(int k = 0; k < numToCopy;k++)
                objects[k]=oldArray[k];// переписываем значения старого вектора в новый
        theSize = numToCopy;//изменяется размер и
        theCapacity = newCapacity;// вместимость 
        delete[] oldArray;// удаляем старый вектор
}
template <class Object>
void vector<Object>::pop_back( )// удаление с конца
{
   if( empty( ) )// если вектор пуст печатаем сообщение
       throw ( "Cannot call pop_back on empty vector" );
    theSize--;// если нет, уменьшаем размер на 1
}
 
template <class Object>
const Object & vector<Object>::back( ) const// что это?
{
   if( empty( ) )
       throw ( "Cannot call back on empty vector" );
        
    return objects[ theSize-1 ];
}
void main() 
{
        vector <int> v[10]; //  вектор v[10] 
        int i = 0;
        for(i = 0;i<10;i++)
                v->push_back(i); // заполняем вектор от 0 до 9 вставляя значения в конец вектора
    
        i = 0;
        int k = v->size();// ? 
        while(i < k)
        {
                cout << v->back();// что значит конструкция ->
                v->pop_back();
                cout << endl;
                i++;
        }
        getch();
 
}
 
}
rivett вне форума Ответить с цитированием
Старый 16.11.2011, 01:41   #2
Son Of Pain
Участник клуба
 
Регистрация: 23.12.2010
Сообщений: 1,129
По умолчанию

Цитата:
шаброн; class object - параметр шаблона?
Да.


Цитата:
explicit следует писать для всех конструкторов с одним параметром
Нет, не для всех. explicid значит "принимать параметры только этого типа, не проводя автоматические преобразования". Не преобразовывать float в int, char в int и т. д.

Цитата:
или theSize и theCapacity тож конструкторы???
Это список инициализаторов полей. То есть такая запись
Код:
explicit vector(int initSize = 0): theSize(initSize),
theCapacity(initSize)
обозначает почти то же самое, что и запись
Код:
explicit vector(int initSize = 0) 
{
	theSize=initSize;
	theCapacity=initSize;
}
Разница в том, что в первом случае поля инициализируются сразу (вызывается конструктор копирования), а во втором сначала создаются конструктором по умолчанию, а потом вызывается оператор присваивания.
Короче говоря - первая запись лучше )

Цитата:
создаем объект с вместимостью theCapacity?
Выделяем память для стольких объектов. Такой велосипедный аналог динамических массивов, которым пользовались бедные программисты на C, пока не появился C++ со своим std::vector.

Цитата:
vector(const vector &rhs): (NULL) // что значит двоеточие после ()?
А это устаревший синтаксис списка инициализаторов, который нормальные компиляторы больше не поддерживают. Кусок справа начиная от двоеточия тут не нужен.

Цитата:
и почему const vector и зачем &rhs
Это называется "конструктор копирования". Он вызывается, если нужно создать новый объект из уже существующего -
Код:
obj o1;
obj o2(o1);
rhs - название параметра, в котором передастся объект-источник. Конструктор копирования не должен его менять, потому он передается как константа; создавать его копию тоже не нужно, потому он передается по ссылке - это быстрее. Вот и получается const&.
Цитата:
{operator = (rhs);}// ?
Конструктор копирования и оператор присваивания выполняют тут практически одинаковую функцию. Чтобы не дублировать код, первый реализован как вызов второго.
Цитата:
bool empty( ) const // это функция ?
Да, функция Возвращает true, если вектор пустой.

Цитата:
Object & operator [] (int index) // а это что?
А это - перегрузка оператора [], чтобы к вектору можно было обращаться, как к обычному массиву.

Цитата:
#ifndef NO_CHECK // директива проверки выхода из области вектора?
Да. Если ее отключить - доступ к элементам будет работать чуть быстрее, но выход за границы проверяться не будет.

Цитата:
throw ArrayIndexOutOfBoundException();// trow - устанавливает тип выбрасываемых исключений?
Устанавливает тип и сразу выбрасывает его

Цитата:
const vector & operator = ( const vector &rhs);//перегрузка =?
Да.


Цитата:
int size()const{return theSize;}// размер вектора? почему сonst?
Слово const после сигнатуры функции обозначает, что она не меняет состояние объекта - т. е. не присваивает новые значения его полям и не вызывает другие функции, которые могут это сделать. Итог - ее можно вызывать даже у константных объектов, например.

Цитата:
const Object & back( ) const;//что это
А это функция, которая возвращает константную ссылку на последний элемент массива.

Цитата:
Object * objects;// что это?
Указатель, который будет показывать на память, выделенную для хранения объектов (тот самый аналог динамического массива).

Цитата:
const vector<Object>&// зачем & ? это же ,bn равный нулю?
vector<Object>:: operator =(const vector<Object>&rhs)
Это оператор присваивания. & там нужен, потому что операторы присваивания всегда должны возвращать ссылку на объект. Чтобы работал код вроде a=b=c=d=0;

Цитата:
if(this != & rhs)// ?
А это устаревший способ реализации перегруженного оператора присваивания. Так писали еще в начале девяностых, пока не научились делать exception-safe код.
Эта проверка нужна, чтобы не допускать присваивания объекта самому себе (a=a; ). this - указатель на объект в левой части присваивания; rhs - объект из правой части. Если они равны - присваивать нельзя, очевидно. )
Но повторюсь - так уже давно никто не пишет.

Цитата:
delete [] objects; // что мы удаляем?
Если мы присваиваем одному вектору значение другого - то, очевидно, должны сначала удалить память, выделенную для его старых элементов.

Цитата:
return *this;// что мы возвращаем?
Ссылку на себя же. Так принято, чтобы можно было писать a=b=c=d=0;

Цитата:
Object *oldArray = objects;// что мы делаем?
Мы сохраняем указатель на место, где раньше были элементы. Выделяем больше памяти в другом месте, и копируем старые элементы туда. А потом освобождаем старое место.

Последний раз редактировалось Son Of Pain; 16.11.2011 в 02:42.
Son Of Pain вне форума Ответить с цитированием
Старый 16.11.2011, 01:47   #3
Son Of Pain
Участник клуба
 
Регистрация: 23.12.2010
Сообщений: 1,129
По умолчанию

Цитата:
int numToCopy = newCapacity<theSize?newCapacity:the Size;// вообще не понятна эта строка; numToCopy - что в этой переменной.
Количество элементов, которые нужно будет копировать. Сокращенная запись if-else, типа
Если мы делаем reserve для меньшего количества элементов, чем было в массиве до этого - то копировать нужно будет не все.


Цитата:
vector <int> v[10]; // вектор v[10]
Это массив из 10 векторов. Потому, чтобы код работал, вместо квадратных скобок должны стоять круглые А еще доступ к нему идет через указатель, потому должно вообще быть написано
Код:
vector<int>* v=new vector<int>(10);

Цитата:
cout << v->back();// что значит конструкция ->
То же самое, что и конструкция *v. - доступ через указатель.


Да, помни, что в этом коде есть пачка недочетов. Для студенческой лабы он сойдет, конечно, но ориентироваться на него не стОит.
Son Of Pain вне форума Ответить с цитированием
Старый 16.11.2011, 02:09   #4
rivett
Новичок
Джуниор
 
Регистрация: 15.11.2011
Сообщений: 2
По умолчанию

Цитата:
Сообщение от Son Of Pain Посмотреть сообщение
Да, помни, что в этом коде есть пачка недочетов. Для студенческой лабы он сойдет, конечно, но ориентироваться на него не стОит.
это прога, которую нам препод на лекции зачитал...она у нас, как он сказал, должна быть образцом.
Son Of Pain, спасибо огромнейшее. просто не хочется в самом начале забрасывать тему, решила поподробней разобраться. еще раз огромнейшее спасибо за подробный ответ
rivett вне форума Ответить с цитированием
Старый 16.11.2011, 02:32   #5
Son Of Pain
Участник клуба
 
Регистрация: 23.12.2010
Сообщений: 1,129
По умолчанию

К сожалению, этот преподаватель не читал базовых книг по c++, в которых объясняется, почему так писать нельзя, тем более в "образцовом" коде

Последний раз редактировалось Son Of Pain; 16.11.2011 в 02:40.
Son Of Pain вне форума Ответить с цитированием
Старый 12.08.2014, 19:10   #6
Леночка13
 
Регистрация: 30.05.2014
Сообщений: 3
Сообщение

поддерживаю, много в коде содержится лишнего.

int capacity()const{ return theCapacity;}// тот же вопрос. при чем тут const

тут ты не ставишь const чтобы не изменить содержимое , а остальное так понимаю тебе уже рассказали.
Леночка13 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
не могу понять... svoi92 Помощь студентам 1 08.02.2011 14:51
не могу понять Dawystrik SQL, базы данных 0 06.09.2009 19:20
не могу понять... Dutchman Паскаль, Turbo Pascal, PascalABC.NET 4 14.12.2006 07:14