2014 dxdy logo

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

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




 
 шаблон класса Vector.
Сообщение04.12.2009, 21:21 
На основе созданного класса 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 
Честно говоря, в таком количестве ошибок просто неохота ковыряться.
Первый вопрос: почему автор не использует стандартный vector<> из STL?
Второй вопрос: почему автор не учится программировать на задачах попроще?

 
 
 
 Re: шаблон класса Vector.
Сообщение04.12.2009, 22:44 
ну так видимо надо.
собственно вопрос.

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

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

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

 
 
 
 Re: шаблон класса Vector.
Сообщение04.12.2009, 23:52 
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 
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 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group