runtime error
Sep 1, 2009 at 9:27am Sep 1, 2009 at 9:27am UTC
Hi all,
Can somebody tell me why this code does not work and how to fix it? It compiles but runtime errors appear:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
#include <iostream>
#include <vector>
using namespace std;
template <class T>
class Vec
{
public :
// constructors
Vec(int length);
Vec(int length, T typeValue);
Vec(const Vec<T>& rhsObj);
const Vec<T>& operator =(const Vec<T>& rhsObj);
const Vec<T>& operator =(T& typeValue);
const Vec<T>& operator *=(T typeVal);
const Vec<T> operator *(T typeVal) const ;
const T& operator ()(int index) const ;
T& operator ()(int index);
int getSize() const ;
~Vec();
private :
vector<T> myVec_;
};
template <class T>
Vec<T>::
Vec(int length)
{
myVec_ = vector<T>(length);
}
template <class T>
Vec<T>::
Vec(int length, T typeValue)
{
myVec_ = vector<T>(length,typeValue);
}
template <class T>
Vec<T>::
Vec(const Vec<T>& rhsObj)
{
vector<T> myVec_(rhsObj.myVec_);
}
template <class T>
const Vec<T>&
Vec<T>::
operator =(const Vec<T>& rhsObj)
{
myVec_ = rhsObj.myVec_;
return *this ;
}
template <class T>
const Vec<T>&
Vec<T>::
operator =(T& typeValue)
{
for (unsigned i = 0; i < myVec_.size(); i++)
(*this )(i) = typeValue;
return *this ;
}
template <class T>
const Vec<T>&
Vec<T>::
operator *=(T typeVal)
{
for (unsigned i = 0; i < myVec_.size(); i++)
{
(*this )(i) *= typeVal;
}
return *this ;
}
template <class T>
const Vec<T>
Vec<T>::
operator *(T typeVal) const
{
return (Vec<T>(*this ) *= typeVal);
}
template <class T>
const T&
Vec<T>::
operator ()(int index) const
{
return myVec_[index];
}
template <class T>
T&
Vec<T>::
operator ()(int index)
{
return myVec_[index];
}
template <class T>
int
Vec<T>::
getSize() const
{
return (myVec_.size());
}
template <class T>
Vec<T>::
~Vec()
{
}
// ******************************************************************************
// overloading externally since the first argument is not an object: typeVal*obj1
// ******************************************************************************
template <class T>
const Vec<T>
operator *(const T typeVal, const Vec<T>& obj1)
{
return (obj1*typeVal);
}
int main()
{
Vec<double > x(3,4);
Vec<double > d = x*2.0;
cout << d(0) << " " << d(1) << " " << d(2) << endl;
return 0;
}
Sep 1, 2009 at 9:36am Sep 1, 2009 at 9:36am UTC
You need to tell us what the error is and when it occurs
Sep 1, 2009 at 1:21pm Sep 1, 2009 at 1:21pm UTC
Your copy constructor is wrong.
You don't even need one; the default member-wise copy version provided by the compiler will suffice.
Sep 1, 2009 at 4:45pm Sep 1, 2009 at 4:45pm UTC
Thanks jsmith. The problem is in the copy constructor. I just commented it and now the code works. Just to understand a little bit more, why the copy constructor defined as above is wrong?
Thanks.
Sep 1, 2009 at 5:01pm Sep 1, 2009 at 5:01pm UTC
You are declaring a variable myVec_ inside the function that shadows the class member myVec_.
The assignment is assigning to the local variable, not to the class member.
Sep 1, 2009 at 5:08pm Sep 1, 2009 at 5:08pm UTC
1 2 3 4 5 6
template <class T>
Vec<T>::
Vec(const Vec<T>& rhsObj)
{
vector<T> myVec_(rhsObj.myVec_);
}
Syntactically it looks like you are simply creating a temporary object within the constructor which happens to have the same name as the class attribute. Since this is the constructor, you'd want to use the initializer list. When it is all said and done, the object that was constructed has an empty myVec_ object. Then you try to make a call to its operator() function will attempts to access an empty vector using its operator[] which causes undefined behavior. You can confirm this by setting breakpoints and stepping into the copy constructor and operator() functions (assuming that they weren't inlined by the compiler). Anyway, as jsmith indicates the copy constructor and assignment operator aren't necessary.
Sep 1, 2009 at 6:33pm Sep 1, 2009 at 6:33pm UTC
ok. thanks jsmith and kempofighter. Now, the correct constructor is:
1 2 3 4 5 6
template <class T>
Vec<T>::
Vec(const Vec<T>& rhsObj)
{
myVec_ = rhsObj.myVec_;
}
or
1 2 3 4 5
template <class T>
Vec<T>::
Vec(const Vec<T>& rhsObj) : myVec_ (rhsObj.myVec_)
{
}
Also, is there any way I can do the following in the main() function:
1 2 3 4 5 6 7
int main()
{
Vec<double > x(3,4);
Vec<double > d = 2*x;
cout << d(0) << " " << d(1) << " " << d(2) << endl;
return 0;
}
without incurring in a compilation error because of 2 can be interpreted as more than one type? I mean I would like this to compile independently if I use 2*x or 2.0*x
Thanks again.
Sep 1, 2009 at 7:10pm Sep 1, 2009 at 7:10pm UTC
user Robertlzw suggested me this:
1 2 3 4 5 6
template <class T, class U>
const Vec<T>
operator *(const U typeVal, const Vec<T>& obj1)
{
return (obj1*typeVal);
}
which actually works pretty good.
Thanks.
Topic archived. No new replies allowed.