runtime error

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;
}
You need to tell us what the error is and when it occurs
Your copy constructor is wrong.

You don't even need one; the default member-wise copy version provided by the compiler will suffice.
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.
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.
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.
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.

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.