2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 шаблон класса Vector.
Сообщение04.12.2009, 21:21 


14/11/09
7
На основе созданного класса Vector разработать шаблон класса Vector , который может содержать как вещественные числа, так и объекты класса
Polynom.
класс полином описан в соседнем топике.
тут topic26798.html

собственно обьявление операторов правильное?
мб другие ошибки присутствуют?
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
template <class T> class Vector
{  
private:
        size_t m_Dim;                                           // Размер вектора.
        T* m_pVec;                                              //адрес массива с координатами вектора
public:
        Vector(size_t, T*);                             //конструктор с 2-мя параметром
        Vector(size_t);                                         //конструктор с 1-им параметром
        Vector();
        Vector(const Vector&);                          //конструктор копирования
        ~Vector();                                                      // Деструктор.
        double GetKof(const size_t i); // Получение i-ой координаты.
        void SetKof(const size_t i, const double x);    // Изменение i-ой координаты.
        size_t GetDim() const {return m_Dim;}   // Получение размера вектора.
        void Show() const;      // Вывод вектора.

        template <class T> Vector<T> Vector<T>::operator+();
        template <class T> Vector<T> Vector<T>::operator-();
        template <class T> Vector<T> & Vector<T> operator+=(const Vector<T> &ob);
        template <class T> Vector<T> & Vector<T> operator+=(T op);
        template <class T> Vector<T> & Vector<T> operator-=(const Vector<T> &ob);
        template <class T> Vector<T> & Vector<T> operator-=(T op);
        template <class T> Vector<T> & Vector<T> operator*=(const Vector<T> &vec);
        template <class T> Vector<T> & Vector<T> operator*=(T op);
        template <class T> Vector<T> & Vector<T> operator^=(int op);
        template <class T> Vector<T> & Vector<T> operator/=(T op);
        template <class T> friend Vector<T> operator+(const Vector<T> &ob1, const Vector<T> &ob2);
        template <class T> friend Vector<T> operator+(const Vector<T> &ob1,T op1);
        template <class T> friend Vector<T> operator-(const Vector<T> ob1, const Vector<T> ob2);
        template <class T> friend Vector<T> operator-(const Vector<T> ob1, T op2);
        template <class T> friend Vector<T> operator*(const T &ob1,const T &ob2);
        template <class T> friend Vector<T> operator*(const T &ob1, T op1);
        template <class T> friend Vector<T> operator/(const T &ob1, T op1);
        template <class T> friend Vector<T> operator^(const T &ob1, int op1);

        template <class T> friend Vector<T> & Vector<T>operator=(const Vector<T> &ob);
        template <class T> friend Vector<T> & Vector<T>operator=(T op);

        friend bool operator==(const Vector<T> &ob1,const Vector<T> &ob2);
        friend bool operator==(const Vector<T> &ob1, T op1);
        friend bool operator!=(const Vector<T> &ob1,const Vector<T> &ob2);
        friend bool operator!=(const Vector<T> &ob1, T op1);

        double &Vector<T>::operator[](const size_t i) const;

        friend istream & operator >>(istream &ris, Vector<T> &rs);
        friend ostream & operator << (ostream &ros, const Vector<T> &cz);

};

template <class T> Vector<T>::double Vector::GetKof(const size_t i)
{
        if (i > m_Dim)
        {
                cout<<szbuf.toOem("Неправильное значение")<<endl;;
                exit(-1);
        }
        return m_pVec[i-1];
}
template <class T> Vector<T>::void Vector::SetKof(const size_t i,const double x )
{
        if (i > m_Dim)
        {
                cout<<szbuf.toOem("Неправильное значение ")<<endl;
                exit(-1);
        }
        m_pVec[i-1]=x;
}

template <class T> Vector<T>::void Vector::Show() const
{
        cout << '(';
        size_t i;
        for (i = 0; i < m_Dim; ++i)
        {
                cout << m_pVec[i];
                if (i < m_Dim - 1) cout << ", ";
        }
        cout << ')' << endl;
}

template <class T> Vector<T>::Vector(const size_t Dim, T*):m_Dim(Dim) // к-ор с 2мя арг
{
        m_pVec=new T[Dim];
        if (!m_pVec)
        {
                cout <<szbuf.toOemA( "Ошибка! Неверный размер вектора." )<< endl;
                exit(-3);
        }
        for(int i=0;i<m_Dim;i++)
                m_pVec[i]=pVec[i];
}
template <class T> Vector<T>::Vector(size_t Dim):m_Dim(Dim) // к-ор с 1им арг
{
        m_pVec= new T[m_Dim=Dim];
        if (!m_pVec)
        {
                cout <<szbuf.toOemA( "Ошибка! Неверный размер вектора." )<< endl;
                exit(-1);
        }
        for(int i=0;i<m_Dim;i++)
                m_pVec[i]=0.0;
}

template <class T> Vector<T>::Vector():m_Dim(0) // к-ор без арг
{
        m_pVec=new T[m_Dim+1];
        if(!m_pVec)
        {
                cout<<"Error"<<endl;
                exit (-1);
        }      
}

template <class T> Vector<T>::Vector(const Vector& cv):m_Dim(cv.m_Dim) //конструктор копирования
{
        if (!(m_pVec=new T[m_Dim]))
        {
                cout<<szbuf.toOemA("Нет памяти") <<endl;
                exit(-1);
        }
        //копирование координат
        size_t i;
        for(i=0;i<m_Dim;++i)
                m_pVec[i]=cv.m_pVec[i];
        cout<<szbuf.toOemA("копия создана Vec") <<endl;
}
template <class T> Vector<T>::~Vector()
{
        cout << szbuf.toOemA("Вектор успешно удалён ...") << endl;
        delete[] m_pVec;

///////////////////////////////////////////////////
/////////////////OPERATORI/////////////////////
//////////////////////////////////////////////////

template <class T> Vector<T> Vector<T>::operator+()
{
        return *this;
}
template <class T> Vector<T> Vector<T>::operator-()
{
        size_t i;
        for(i=0;i <= m_Dim; ++i)
                m_pVec[i]=-m_pVec[i];
        return *this;
}

template <class T> Vector<T> & Vector<T>::operator+=(const Vector<T> &ob)
{
        if (&ob != this)
        {
                size_t i,k,j;

                if (m_Dim > ob.m_Dim)
                {
                        i = m_Dim;
                        k=ob.m_Dim;
                }
                else
                {
                        i = ob.m_Dim;
                        k = m_Dim;
                }

                T* new_Vec = new T[i];

                for(j=0; j<=k; ++j)
                        new_Vec[j] = m_pVec[j]+ob.m_pVec[j];

                for(j=k; j<=i; ++j)
                        if (m_Dim > ob.m_Dim)
                                new_Vec[j] = m_pVec[j];
                        else
                                new_Vec[j] = ob.m_pVec[j];

                m_pVec = new_Pol;
                m_Dim = i;
        }
        return *this;
}
template <class T> Vector<T> & Vector<T>::operator-=(const Vector<T> &ob)
{
        if (&ob != this)
        {
                size_t i,k,j;

                if (m_Dim > ob.m_Dim)
                {
                        i = m_Dim;
                        k=ob.m_Dim;
                }
                else
                {
                        i = ob.m_Dim;
                        k = m_Dim;
                }

                T* new_Vec = new T[i];

                for(j=0; j<=k; ++j)
                        new_Vec[j] = m_pVec[j]-ob.m_pVec[j];

                for(j=k; j<=i; ++j)
                        if (m_Dim > ob.m_Dim)
                                new_Vec[j] = -m_pVec[j];
                        else
                                new_Vec[j] = -ob.m_pVec[j];

                m_pVec = new_Pol;
                m_Dim = i;
        }
        return *this;
}

template <class T> Vector<T> & Vector<T>::operator-=(T op)
{
        size_t i;
        for(i=0; i<=m_Dim; ++i)
                m_pVec[i] -= op;
        return *this;
}
template <class T> Vector<T> & Vector<T>::operator+=(T op)
{
        size_t i;
        for(i=0; i<=m_Dim; ++i)
                m_pVec[i] += op;
        return *this;
}
template <class T> Vector<T> & Vector<T>::operator*=(const Vector<T> &vec)
{
        Vector<T> tmp(m_Dim,m_pVec);
        m_Dim=tmp.m_Dim+vec.m_Dim;

        delete [] m_pVec;

        if(!(m_pVec= new T[m_Dim]))
        {
                cout << szbuf.toOemA("Ошибка! Недостаточно памяти!") << endl;
                exit(-1);
        }
        size_t i,j;

        for(i=0;i<=m_Dim;++i)
        {
                m_pVec[i]=0;
        }
        for(i=0; i <= tmp.m_Dim; i++)
        {
                for(j=0; j <= vec.m_Dim; j++)
                {
                        m_pVec[i+j] += tmp.m_pVec[i]*vec.m_pVec[j];
                }
        }
        return *this;
}

//для случая,когда правый операнд число
template <class T> Vector<T> & Vector<T>::operator*=(T op)
{
        size_t i;
        for(i=0; i <= m_Dim; ++i)
                m_Pol[i] *= op;
        return *this;
}

template <class T> Vector<T> & Vector<T>::operator^=(int op)
{
        if (op > 0)
        {
                size_t i;

                Vector<T> temp = *this;
                for (i=0;i <= op;++i)
                {
                        *this *= temp;
                }
        }
        return *this;
}

template <class T> Vector<T> & Vector<T>::operator/=(T op)
{
        if (op!=0)
        {
                size_t i;
                for(i=0; i<=m_Dim; ++i)
                        m_pVec[i] /= op;

                return *this;  
        }
        else cout<<szbuf.toOem("На ноль делить нельзя")<<endl;
}

template <class T> Vector<T> operator+(const Vector<T> &ob1, const Vector<T> &ob2)
{
        Vector<T> temp(ob1);
        return temp+=ob2;

}

template <class T> Vector<T> operator+(const Vector<T> &ob1, T op1)
{
        Polynom temp(ob1);
        return temp+=op1;

}

template <class T> Vector<T> operator-(const Vector<T> ob1, const Vector<T> ob2)
{
        Vector<T> temp(ob1);
        return temp-=ob2;

}

template <class T> Vector<T> operator-(const Vector<T> ob1, T op1)
{
        Vector<T> temp(ob1);
        return temp-=op1;

}

template <class T> Vector<T> operator * (const Vector<T>  &ob1,const Vector<T>  &ob2)
{
        Polynom temp(ob1);
        return temp*=ob2;
}

template <class T> Vector<T> operator * (const Vector<T> &ob1, T op2)
{
        Vector<T> temp(ob1);
        return temp*=op2;
}

template <class T> Vector<T> operator / (const Vector<T> ob1, T op2)
{
        Vector<T> temp(ob1);
        return temp/=op2;
}

template <class T> Vector<T> operator^(const Vector<T> &ob1, int op2)
{
        Vector<T> temp(ob1);
        return temp^=op2;
}
template <class T> Vector<T> & Vector<T>::operator=(const Vector<T> &ob)
{
        if (this != &ob)
        {
                delete[] m_pVec;

                if (!(m_Pol=new T[m_Dim=ob.m_Dim]))
                {
                        cout<<szbuf.toOem("Ошибка! Недостаточно памяти!")<<endl;;
                        exit(-1);
                }
                size_t i;

                for (i=0; i <= m_Dim; ++i)
                        m_pVec[i]=ob.m_pVec[i];
        }
        return *this;
}

template <class T> Vector<T> & Vector<T>::operator=(T op)
{
        *this=op;
        return *this;
}

bool operator==(const Vector<T> &ob1,const Vector<T> &ob2)
{
        if(ob1.m_Dim!=ob2.m_Dim)
        {
                return false;

                for(size_t i=0; i<=ob1.m_Dim; ++i)
                {
                        if(ob1.m_pVec[i] != ob2.m_pVec[i])
                        {
                                return false;
                        }
                }
                return true;
        }
}
bool operator==(const Vector<T> &ob1, T op1)
{
        size_t i;
        for(i=0; i<=ob1.m_Dim; ++i)
        {
                if(ob1.m_pVec[i] != op1)
                {
                        return false;
                }
        }
        return true;
}

bool operator!=(const Vector<T> &ob1,const Vector<T> &ob2)
{
        return !(ob1 == ob2);
}

bool operator!=(const Vector<T> &ob1, T op1)
{
        return !(ob1 == op1);
}

double &Vector<T>::operator[](const size_t i) const
{
        if (i <= m_Dim)
                return m_pVec[i];
        else
                cout<<szbuf.toOem("Ошибка!")<<endl;
        exit(-1);        
}

istream & operator >>(istream &ris, Vector<T> &rs)
{
        for (size_t i(0); i <= rs.m_Dim; i++)
                cin>>rs.m_pVec[i];
        return ris;
}

ostream & operator << (ostream &ros, const Vector<T> &cz)
{
        cz.ShowVec();
        return ros;
}

 

 Профиль  
                  
 
 Re: шаблон класса Vector.
Сообщение04.12.2009, 22:15 
Заслуженный участник


04/05/09
4584
Честно говоря, в таком количестве ошибок просто неохота ковыряться.
Первый вопрос: почему автор не использует стандартный vector<> из STL?
Второй вопрос: почему автор не учится программировать на задачах попроще?

 Профиль  
                  
 
 Re: шаблон класса Vector.
Сообщение04.12.2009, 22:44 


14/11/09
7
ну так видимо надо.
собственно вопрос.

template <class T> Vector<T> & operator+=(const T &ob);
Vector<T> & operator+=(const Vector<T> &ob);

в каких случаях применяется та, или иная реализация.
просто везде по разному.

есть ли толк в обьявлении дружественных функция в template классе?

 Профиль  
                  
 
 Re: шаблон класса Vector.
Сообщение04.12.2009, 23:52 
Заслуженный участник


04/05/09
4584
inlaf в сообщении #268053 писал(а):
ну так видимо надо.
Это не ответ.

inlaf в сообщении #268053 писал(а):
собственно вопрос.

template <class T> Vector<T> & operator+=(const T &ob);
Никогда такого не встречал, и не могу придумать зачем такое может понадобиться.

inlaf в сообщении #268053 писал(а):
Vector<T> & operator+=(const Vector<T> &ob);
А вот такое бывает, хотя и не часто. Обычно встречается что-то типа:
Vector<T> & operator+=(const T &ob);

inlaf в сообщении #268053 писал(а):
в каких случаях применяется та, или иная реализация.
просто везде по разному.
Всё зависит от требований. Вам сначала надо разобраться, что же вы хотите получить, а потом уже заниматься реализацией. Когда вам известны требования, выбор API довольно однозначен. Для сравнения рекомендую посмотреть на стандартную реализацию вектора в STL: http://www.sgi.com/tech/stl/Vector.html

inlaf в сообщении #268053 писал(а):
есть ли толк в обьявлении дружественных функция в template классе?
Толк есть, если есть необходимость.

 Профиль  
                  
 
 Re: шаблон класса Vector.
Сообщение06.12.2009, 02:19 
Заслуженный участник


26/07/09
1559
Алматы
2inlaf
Цитата:
собственно вопрос.

template <class T> Vector<T> & operator+=(const T &ob);
Vector<T> & operator+=(const Vector<T> &ob);

в каких случаях применяется та, или иная реализация.
просто везде по разному.

Ну давайте сначала посмотрим на второй вариант. Вот пример:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
template <class Type>
struct Class1
{
    Class1<Type> &operator += (const Class1<Type> &);

    const Type &GetField() const {return Field;}

    private: Type Field;
};

template <class Type>
Class1<Type> &Class1<Type>::operator += (const Class1<Type> &Object)
{
    Field=Object.GetField();

    return *this;
}
 

Теперь, если мы захотим для объектов A и B классов Class1<...> написать выражение A+=B, то оно скомпилируется только если оба операнда будут одного типа, например Class1<char>.

Теперь приведу пример, похожий на ваш первый вариант:
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
template <class Type>
struct Class2
{
    template <class RightType>
    Class2<Type> &operator += (const Class2<RightType> &);

    const Type &GetField() const {return Field;}

    private: Type Field;
};

template <class Type>
template <class RightType>
Class2<Type> &Class2<Type>::operator += (const Class2<RightType> &Object)
{
    Field=Object.GetField();

    return *this;
}
 

Теперь выражение A+=B будет работать даже если операнды будут иметь разные типы, лишь бы они были совместимы в том смысле, что если объекты объявлены как Class2<Type1> A; Class2<Type2> B, то Type1 должен либо совпадать с Type2, либо должен быть его суперклассом (предком), либо, в общем случае, просто должно существовать преобразование Type2->Type1 (неважно, через определение оператора преобразования типов или через перегрузку операторов присваивания или ещё каким макаром).

Nota bene, что конструкцию template <class Type> template <class RightType> нужно записывать именно так, а не сокращенно как template <class Type, class RightType>.

Конечно, именно то, что вы написали выглядит очень странным, я про template <class T> Vector<T> & operator+=(const T &ob) говорю. Но так может выглядеть, например, объявление глобального (non-member) оператора, только в этом случае аргументов у него будет два. Или вы просто template <class T> зря написали, писать это перед каждым объявлением (прототипом) не нужно, только перед определением (реализацией). Кажется, именно в этом ваша ошибка (хотя их и так хватает в приведенном вами коде)... :)

Дальше.

Стиль обработки run-time ошибок, это вообще улет. :) Смотрите в сторону нормальных exception'ов.

Также вы очень странно определяете логику в некоторых перегруженных операторах, через бесконечную рекурсию. :)

В операторе [] вообще выхода в одной из ветвей нет (нормального return'а)...

Ужасть... Неужели, оно собирается и работает?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 5 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group