Need help with dynamic arrays + operators!

So I have created a dynamic array class and I want to do some operator overloading on these arrays. For example, c = a + b, where a,b, and c are all arrays of my created class. I want this to work out: c[i] = a[i] + b[i] for all the values i. also, I need help on the += operator! for example, a += 3, causing a[0], a[1],....,a[i] to all increase in value by 3. Here is the header and cpp file for my created array class! Thanks a bunch! on a side note, the + and * operator functions are required to be global, whereas += is a public operator.

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
  class VectorFloat 
{
public:

	VectorFloat();  //creates an empty array of size 0
	VectorFloat(int n);  //create an array of given size
	VectorFloat(VectorFloat &vec); //copy constructor
	~VectorFloat();  //destructor

	int size() {return m_dim;}  //returns size of vector

	float& operator[](int i);

	VectorFloat& operator += (VectorFloat &vec);

	void operator = (VectorFloat &vec);

private:

	float *m_p;  //dynamically allocated array of objects; the vector itself
	int m_dim;  //the size of the object
};

VectorFloat operator+ (VectorFloat &vec_1, VectorFloat &vec_2);
	 
VectorFloat operator* (VectorFloat &vec_1, VectorFloat &vec_2);


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
  #include "VectorFloat.h"
#include <iostream>

VectorFloat :: VectorFloat()
{
	m_dim = 0;
	m_p=NULL;
}

VectorFloat :: VectorFloat(int n)
{
	m_dim = n;

	if (m_dim>0)
	{
		m_p = new float [m_dim];
	}
	else
	{
		m_p=NULL;
	}
}

float& VectorFloat :: operator[] (int i) 
{
	return m_p[i];
}

VectorFloat :: VectorFloat (VectorFloat &vec) 
{
	for (int i=0;i<m_dim;i++)
	{
		m_p[i] = vec[i];
	}
}

VectorFloat :: ~VectorFloat() 
{
	delete [] m_p;
}


VectorFloat& VectorFloat :: operator += (VectorFloat &vec)
{
	for (int i=0;i<m_dim;i++)
	{
		vec[i]+=1;
	}
}

void VectorFloat :: operator = (VectorFloat &vec) 
{
	for (int i=0;i<m_dim;i++)
	{
		m_p[i] = vec[i];
	}
}

VectorFloat operator+ (VectorFloat &vec_1, VectorFloat &vec_2)  //no need for :: since it is a global function outside of the VectorFloat class
{
	int sz_1 = vec_1.size();
	int sz_2 = vec_2.size();

	if (sz_2 < sz_1)
	{
		sz_1 = sz_2;
	}

	VectorFloat a(sz_1);

	for (int i=0;i<sz_1;i++)
	{
		a[i] = vec_1[i] + vec_2[i];
	}

	return a;
}  

VectorFloat operator* (VectorFloat &vec_1, VectorFloat &vec_2) 
{
	int sz_1 = vec_1.size();
	int sz_2 = vec_2.size();

	if (sz_2 < sz_1)
	{
		sz_1 = sz_2;
	}

	VectorFloat a(sz_1);

	for (int i=0;i<sz_1;i++)
	{
		a[i] = vec_1[i]*vec_2[i];
	}

	return a;
}
43
44
45
46
47
48
49
VectorFloat& VectorFloat :: operator += (VectorFloat &vec)
{
	for (int i=0;i<m_dim;i++)
	{
		vec[i]+=1;
	}
}


If you want to add an int (err, maybe float?) to your VectorFloat then the above makes no sense. You also forget to return the object.

1
2
3
4
5
6
7
8
9
VectorFloat& VectorFloat :: operator += (float n)
{
	for (int i=0;i<m_dim;i++)
	{
		vec[i]+=n;
	}

	return *this;
}


I want this to work out: c[i] = a[i] + b[i] for all the values i

From a quick look, I don't see what the problem is... the operator[] seems correct.

Or you want it to work "for all values i"? You can't, the value of i is limited by the size of your vector.

For example if you have 3 elements, then you can access v[0], v[1] and v[2].
You cannot access v[3], v[5], or v[100] because they don't exist!
1. Make the code const correct. int size() const { return m_dim; } //returns size of vector etc.

2. Guard against out of bounds access in operator+= etc.

3. For the copy constructor and copy assignment deep copies are required
1
2
3
4
5
6
7
VectorFloat :: VectorFloat (VectorFloat &vec) 
{
	for (int i=0;i<m_dim;i++) // *** m_dim is uninitialized
	{
		m_p[i] = vec[i]; // *** as is m_p[i]
	}
}


4. Prefer overloading operator+ etc. as non-friend, non-member functions


Something like this:

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
#include <iostream>
#include <iomanip>
#include <cstdlib>

inline int smaller_of( int a, int b ) { return a<b ? a : b ; }

class VectorFloat
{
public:

	VectorFloat() //creates an empty array of size 0
	   : m_p(nullptr), m_dim(0) {}

	VectorFloat(int n)  //create an array of given size
       : m_p( new float[n]{} ), m_dim(n) {}

	VectorFloat( const VectorFloat &vec )  //copy constructor; deep copy
	   : m_p( new float[vec.m_dim] ), m_dim(vec.m_dim)
	   { for( int i = 0 ; i < m_dim ; ++i ) m_p[i] = vec.m_p[i] ; }

	~VectorFloat() noexcept //destructor
	{ delete[] m_p ; }

	VectorFloat& operator = ( VectorFloat &vec ) // copy assignment; deep copy
	{
            if( &vec != this ) // guard against self-assignment
            {
                // if( m_dim < vec.m_dim ) // resize (if required)
                {
                    delete[] m_p ;
                    m_p = new float[ vec.m_dim ] ;
                }
                m_dim = vec.m_dim ;
                for( int i = 0 ; i < m_dim ; ++i ) m_p[i] = vec.m_p[i] ;
            }
            return *this ;
	}

	// note: move construtor amd move assignment are implicitly deleted

	int size() const { return m_dim; }  //returns size of vector

	float& operator[] (int i) { quit_if_bad_index(i) ; return m_p[i] ; }
	const float& operator[] (int i) const { quit_if_bad_index(i) ; return m_p[i] ; }

	VectorFloat& operator += ( const VectorFloat &vec )
	{
	    for( int i = 0 ; i < smaller_of(m_dim,vec.m_dim) ; ++i )
	        m_p[i] += vec.m_p[i] ;
	    return *this ;
	}

	VectorFloat& operator *= ( const VectorFloat &vec )
	{
	    for( int i = 0 ; i < smaller_of(m_dim,vec.m_dim ) ; ++i )
	        m_p[i] *= vec.m_p[i] ;
	    return *this ;
	}

private:

	float *m_p;  //dynamically allocated array of objects; the vector itself
	int m_dim;  //the size of the object

	void quit_if_bad_index( int i ) const // exit if index is invalid
	{
            if( i < 0 || i >= m_dim )
            {
                std::cerr << "VectorFloat index is out of range!" ;
                std::exit(1) ;
            }
	}
};

// prefer non-friend, non-member
VectorFloat operator + ( VectorFloat first, const VectorFloat& second )
{ return first += second ; } // note: first is passed by value

VectorFloat operator * ( VectorFloat first, const VectorFloat& second )
{ return first *= second ; } // note: first is passed by value

std::ostream& operator<< ( std::ostream& stm, const VectorFloat& seq )
{
    stm << " [" << std::fixed << std::showpoint << std::setprecision(2) ;
    for( int i = 0 ; i < seq.size() ; ++i ) stm << std::setw(6) << seq[i] << ' ' ;
    return stm << "] " ;
}

int main()
{
     VectorFloat a(6) ;
     { int i = 0 ; for( int v : { 1, 2, 3, 4, 5, 6 } ) a[i++] = v ; }
     std::cout << "a: " << a << '\n' ;

     VectorFloat b(4) ;
     { int i = 0 ; for( int v : { 7, 8, 9, 10 } ) b[i++] = v ; }
     std::cout << "b: " << b << '\n' ;

     const auto c = a + b ; // operator+ => copy constructor, operator +=
     std::cout << "c: " << c << '\n' ;

     const auto d = a * c ;
     std::cout << "d: " << d << '\n' ;

     const auto e = d ; // copy assignment
     std::cout << "e: " << e << '\n' ;
}

http://coliru.stacked-crooked.com/a/acbc3fe41feaf4f8
@ JLBorges:
// note: move construtor amd move assignment are implicitly deleted
I didn't know this was normal behavior. How come it is so?

Also instead of using quit_if_bad_index() shouldn't we throw an exception, such as std::out_of_range?

@ zumi: be advised that JLBorges uses elements of C++11 (the C++ standard of 2011).
Your compiler must have good support for C++11 or it won't be able to compile the code JLBorges provided.
Last edited on
> // note: move construtor amd move assignment are implicitly deleted
>> I didn't know this was normal behavior. How come it is so?

My mistake. What I wanted to convey was that the class does not support move semantics.

The comment should have been:
// note: move construtor amd move assignment are not implicitly declared


> Also instead of using quit_if_bad_index() shouldn't we throw an exception, such as std::out_of_range?

Yes; but I was not sure that Zumi was familiar with exceprtions.

Ideally I would prefer unchecked access for [], and an at() that provided checked access (a la vector).

The general C++ philosophy is:
Don't penalize programmers who write correct code for( int i = 0 ; i < seq.size() ; ++i ) seq[i] = 8 ;
because someone else may write incorrect code.
But provide for a slower checked option for use in situations where it may be required.


> JLBorges uses elements of C++11

In the class itself, this is the only C++11 specific construct m_p( new float[n]{} ) ; everything else is C++98 compatible. EDIT: And the noexcept for the destructor.

In main(), yes - range-based for on initializer lists
Last edited on
Thanks a lot guys for all your help and prompt and detailed responses! :)
Towards JLBorges code, is there any way to do the + and * without using the previous *= and += operator? also, for the += operator, that allows the use of vectorfloat += vectorfloat. however, is there any way to make it so that the user can do something like:

VectorFloat a(3);

a+=3;

To make the values of a[0], a[1], a[2] all increase by a value of 3?

Thanks a bunch!
> is there any way to do the + and * without using the previous *= and += operator?

Yes.
Once you have understood how the copy constructor and += *= operators work, you would be able to do that on your own quite easily.



> is there any way to make it so that the user can do something like:
> VectorFloat a(3);
> a+=3;
> To make the values of a[0], a[1], a[2] all increase by a value of 3?

Yes. Overload VectorFloat& VectorFloat::operator += ( float f ) ;.
And for a = a + 3 ; overload VectorFloat operator + ( VectorFloat vec, float f) ;
I got it to work! I just had to play around with it a bit!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
VectorFloat operator* (const VectorFloat &vec_1, const VectorFloat &vec_2) 
{
	VectorFloat a(smaller_of(vec_1.size(), vec_2.size()));
	
	VectorFloat vec_1a(vec_1.size()), vec_2a(vec_2.size());

	vec_1a = vec_1;  vec_2a = vec_2;
	

	for(int i = 0 ; i<smaller_of(vec_1.size(), vec_2.size()) ; i++)
	{
		a[i] = vec_1a[i] * vec_2a[i];
	}

	return a;
}


thanks alot guys :)

So the part 2 of my assignment requires me to run this code to "test" the code that I made, but there are quite a number of errors that show up and I have no idea how to fix it. Heres the required code to run:

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
#include <iostream>
#include "VectorFloat.h"

using namespace std;

void printVF(char const* name, VectorFloat const& vf) {
    cout << "VectorFloat: " << name << endl;
    for (int i = 0; i < vf.size(); ++i) {
        cout << "  [" << i << "] :  " << vf[i] << endl;
    }
}

void part2_test() {
    VectorFloat vf1(3);
    VectorFloat vf2(3);

    vf1[0] = 1.0;
    vf1[1] = 2.0;
    vf1[2] = 3.0;

    vf2[0] = 3.0;
    vf2[1] = 2.0;
    vf2[2] = 1.0;

    printVF("vf1 start", vf1);
    printVF("vf2 start", vf2);
    printVF("vf1 + vf2", vf1 + vf2);
    vf1 += 4;
    printVF("vf1 after (vf1 += 4)", vf1);
    vf1 = vf2;
    printVF("vf1 after (vf1 = vf2)", vf1);
	cout << " dot product vf1 * vf2 = " << (vf1 * vf2)  << endl;

}


These are the errors:
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
1
1>  main.cpp
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\vectorfloat.h(3): error C2011: 'VectorFloat' : 'class' type redefinition
1>          c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\vectorfloat.h(3) : see declaration of 'VectorFloat'
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(8): error C2027: use of undefined type 'VectorFloat'
1>          c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\vectorfloat.h(3) : see declaration of 'VectorFloat'
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(8): error C2228: left of '.size' must have class/struct/union
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(9): error C2678: binary '[' : no operator found which takes a left-hand operand of type 'const VectorFloat' (or there is no acceptable conversion)
1>          c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\vectorfloat.h(13): could be 'float &VectorFloat::operator [](int)'
1>          while trying to match the argument list '(const VectorFloat, int)'
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(14): error C2079: 'vf1' uses undefined class 'VectorFloat'
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(15): error C2079: 'vf2' uses undefined class 'VectorFloat'
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(17): error C2109: subscript requires array or pointer type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(18): error C2109: subscript requires array or pointer type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(19): error C2109: subscript requires array or pointer type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(21): error C2109: subscript requires array or pointer type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(22): error C2109: subscript requires array or pointer type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(23): error C2109: subscript requires array or pointer type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(25): error C2664: 'printVF' : cannot convert parameter 2 from 'int' to 'const VectorFloat &'
1>          Reason: cannot convert from 'int' to 'const VectorFloat'
1>          Source or target has incomplete type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(26): error C2664: 'printVF' : cannot convert parameter 2 from 'int' to 'const VectorFloat &'
1>          Reason: cannot convert from 'int' to 'const VectorFloat'
1>          Source or target has incomplete type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(27): error C2664: 'printVF' : cannot convert parameter 2 from 'int' to 'const VectorFloat &'
1>          Reason: cannot convert from 'int' to 'const VectorFloat'
1>          Source or target has incomplete type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(29): error C2664: 'printVF' : cannot convert parameter 2 from 'int' to 'const VectorFloat &'
1>          Reason: cannot convert from 'int' to 'const VectorFloat'
1>          Source or target has incomplete type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(31): error C2664: 'printVF' : cannot convert parameter 2 from 'int' to 'const VectorFloat &'
1>          Reason: cannot convert from 'int' to 'const VectorFloat'
1>          Source or target has incomplete type
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Last edited on
> The error is: "VectorFloat" has no suitable copy constructor when I tried to do vec_1a = vec_1 ;

The copy constructor that you have written is not const-correct.

1
2
3
4
5
6
7
8
9
10
11
class VectorFloat
{
public:
        // ...

        // VectorFloat( VectorFloat& vec ) ; // **** bad; not const-correct

	VectorFloat( const VectorFloat& vec ) ; // good; const-correct

        // ...
};

See: http://www.parashift.com/c++-faq-lite/const-correctness.html
Oh I realized that and have already made those changes to const correct!

part2_testing.h
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
#include <iostream>
#include "VectorFloat.h"

using namespace std;

void printVF(char const* name, const VectorFloat &vf) {
    
	VectorFloat vf_a(vf.size());
	vf_a=vf;
	cout << "VectorFloat: " << name << endl;
    for (int i = 0; i < vf_a.size(); ++i) {
        cout << "  [" << i << "] :  " << vf_a[i] << endl;
    }
}

void part2_test() {

    VectorFloat vf1(3);
    VectorFloat vf2(3);

    vf1[0] = 1.0;
    vf1[1] = 2.0;
    vf1[2] = 3.0;

    vf2[0] = 3.0;
    vf2[1] = 2.0;
    vf2[2] = 1.0;

    printVF("vf1 start", vf1);
    printVF("vf2 start", vf2);
    printVF("vf1 + vf2", vf1 + vf2);
    vf1 += 4;
    printVF("vf1 after (vf1 += 4)", vf1);
    vf1 = vf2;
    printVF("vf1 after (vf1 = vf2)", vf1);
	cout << " dot product vf1 * vf2 = " << (vf1 * vf2)  << endl;

}


VectorFloat.cpp
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
#include "VectorFloat.h"
#include <iostream>
#include <iomanip>
#include <cstdlib>

inline int smaller_of( int a, int b ) 
{ 
	if (a<b) {return a;}
	else {return b;}
}

VectorFloat :: VectorFloat()
	:m_p(NULL), m_dim(0){}

VectorFloat :: VectorFloat(int n)
{
	m_dim = n;

	if (m_dim>0)
	{
		m_p = new float [m_dim];
	}
	else
	{
		m_p=NULL;
	}
}

float& VectorFloat :: operator[] (int i) 
{
	return m_p[i];
}

VectorFloat :: VectorFloat (VectorFloat const &vec) //Copy constructor ; deep copy
{
	m_p = new float [vec.m_dim];
	m_dim = vec.m_dim;

	for (int i=0;i<m_dim;i++)
	{
		m_p[i] = vec.m_p[i];
	}
}

VectorFloat :: ~VectorFloat()
{
	delete [] m_p;
}


VectorFloat& VectorFloat :: operator += (const float n)

{
	for (int i=0;i<m_dim;i++)
	{
		m_p[i] += n;
	}
	return *this;
}


VectorFloat& :: VectorFloat :: operator = (const VectorFloat &vec) 
{
	if (&vec != this)
	{
		if (m_dim < vec.m_dim)
		{
			delete [] m_p;
			m_p = new float [vec.m_dim];
		}
		m_dim = vec.m_dim;
		for (int i=0;i<m_dim;i++)
		{
			m_p[i] = vec.m_p[i];
		}
	}
	return *this;
}

VectorFloat operator+ (const VectorFloat &vec_1, const VectorFloat &vec_2)  //no need for :: since it is a global function outside of the VectorFloat class
{
	VectorFloat a(smaller_of(vec_1.size(), vec_2.size()));
	
	VectorFloat vec_1a(vec_1.size()), vec_2a(vec_2.size());

	vec_1a = vec_1;  vec_2a = vec_2;
	

	for(int i = 0 ; i<smaller_of(vec_1.size(), vec_2.size()) ; i++)
	{
		a[i] = vec_1a[i] + vec_2a[i];
	}

	return a;

}  

VectorFloat operator* (const VectorFloat &vec_1, const VectorFloat &vec_2) 
{
	VectorFloat a(smaller_of(vec_1.size(), vec_2.size()));
	
	VectorFloat vec_1a(vec_1.size()), vec_2a(vec_2.size());

	vec_1a = vec_1;  vec_2a = vec_2;
	

	for(int i = 0 ; i<smaller_of(vec_1.size(), vec_2.size()) ; i++)
	{
		a[i] = vec_1a[i] * vec_2a[i];
	}

	return a;
}


Errors:

1
2
3
4
5
6
7
8
9
10
11
12
13
1
1>  main.cpp
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\vectorfloat.h(3): error C2011: 'VectorFloat' : 'class' type redefinition
1>          c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\vectorfloat.h(3) : see declaration of 'VectorFloat'
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(8): error C2027: use of undefined type 'VectorFloat'
1>          c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\vectorfloat.h(3) : see declaration of 'VectorFloat'
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(8): error C2228: left of '.size' must have class/struct/union
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(8): error C2079: 'vf_a' uses undefined class 'VectorFloat'
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(8): fatal error C1903: unable to recover from previous error(s); stopping compilation
1>  Generating Code...
1>  Compiling...
1>  VectorFloat.cpp
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Do not define your function inside headers. Only put the declaration there.

1
2
3
4
5
6
7
// definition, should always go in cpp file
int function(int i)
{
    return i;
}

int function(int); // declaration, should go in header file 


Also you forgot the header guards.
You need to use header guards or #pragma once to prevent the multiple inclusion of your header, which will result in a "redefinition" error.

http://en.wikipedia.org/wiki/Include_guard
http://en.wikipedia.org/wiki/Pragma_once
Okay so the part2_testing doesn't work at all. It was a given code by the professor that will be used by him to test the VectorFloat class.

I don't understand why the errors occur. I dont see why it says VectorFloat is an undefined class.

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
#include <iostream>
#include "VectorFloat.h"
#pragma

using namespace std;

/*void printVF(char const* name, const VectorFloat &vf) {
    
	VectorFloat vf_a(vf.size());
	vf_a=vf;
	cout << "VectorFloat: " << name << endl;
    for (int i = 0; i < vf_a.size(); ++i) {
        cout << "  [" << i << "] :  " << vf_a[i] << endl;
    }
}*/

void part2_test() {

    VectorFloat vf1(3);
    VectorFloat vf2(3);

    vf1[0] = 1;
    vf1[1] = 2;
    vf1[2] = 3;

    vf2[0] = 3;
    vf2[1] = 2;
    vf2[2] = 1;

    //printVF("vf1 start", vf1);
   // printVF("vf2 start", vf2);
   // printVF("vf1 + vf2", vf1 + vf2);
    vf1 += 4;
  //  printVF("vf1 after (vf1 += 4)", vf1);
    vf1 = vf2;
   // printVF("vf1 after (vf1 = vf2)", vf1);
	cout << " dot product vf1 * vf2 = " << (vf1 * vf2)  << endl;

}


VectorFloat.cpp
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
#include "VectorFloat.h"
#include <iostream>
#include <iomanip>
#include <cstdlib>

inline int smaller_of( int a, int b ) 
{ 
	if (a<b) {return a;}
	else {return b;}
}

VectorFloat :: VectorFloat()
	:m_p(NULL), m_dim(0){}

VectorFloat :: VectorFloat(int n)
{
	m_dim = n;

	if (m_dim>0)
	{
		m_p = new float [m_dim];
	}
	else
	{
		m_p=NULL;
	}
}

float& VectorFloat :: operator[] (int i) 
{
	return m_p[i];
}

VectorFloat :: VectorFloat (VectorFloat const &vec) //Copy constructor ; deep copy
{
	m_p = new float [vec.m_dim];
	m_dim = vec.m_dim;

	for (int i=0;i<m_dim;i++)
	{
		m_p[i] = vec.m_p[i];
	}
}

VectorFloat :: ~VectorFloat()
{
	delete [] m_p;
}


VectorFloat& VectorFloat :: operator += (const float n)

{
	for (int i=0;i<m_dim;i++)
	{
		m_p[i] += n;
	}
	return *this;
}


VectorFloat& :: VectorFloat :: operator = (const VectorFloat &vec) 
{
	if (&vec != this)
	{
		if (m_dim < vec.m_dim)
		{
			delete [] m_p;
			m_p = new float [vec.m_dim];
		}
		m_dim = vec.m_dim;
		for (int i=0;i<m_dim;i++)
		{
			m_p[i] = vec.m_p[i];
		}
	}
	return *this;
}

VectorFloat operator+ (const VectorFloat &vec_1, const VectorFloat &vec_2)  //no need for :: since it is a global function outside of the VectorFloat class
{
	VectorFloat a(smaller_of(vec_1.size(), vec_2.size()));
	
	VectorFloat vec_1a(vec_1.size()), vec_2a(vec_2.size());

	vec_1a = vec_1;  vec_2a = vec_2;
	

	for(int i = 0 ; i<smaller_of(vec_1.size(), vec_2.size()) ; i++)
	{
		a[i] = vec_1a[i] + vec_2a[i];
	}

	return a;

}  

VectorFloat operator* (const VectorFloat &vec_1, const VectorFloat &vec_2) 
{
	VectorFloat a(smaller_of(vec_1.size(), vec_2.size()));
	
	VectorFloat vec_1a(vec_1.size()), vec_2a(vec_2.size());

	vec_1a = vec_1;  vec_2a = vec_2;
	

	for(int i = 0 ; i<smaller_of(vec_1.size(), vec_2.size()) ; i++)
	{
		a[i] = vec_1a[i] * vec_2a[i];
	}

	return a;
}


errors:
1
2
3
4
5
6
7
8
9
10
11
12
1
1>  main.cpp
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\vectorfloat.h(4): error C2011: 'VectorFloat' : 'class' type redefinition
1>          c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\vectorfloat.h(4) : see declaration of 'VectorFloat'
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(19): error C2079: 'vf1' uses undefined class 'VectorFloat'
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(20): error C2079: 'vf2' uses undefined class 'VectorFloat'
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(22): error C2109: subscript requires array or pointer type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(23): error C2109: subscript requires array or pointer type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(24): error C2109: subscript requires array or pointer type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(26): error C2109: subscript requires array or pointer type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(27): error C2109: subscript requires array or pointer type
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\part2_testing.h(28): error C2109: subscript requires array or pointer type
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Your header should look like this:

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef VECTOR_FLOAT_H_INCLUDED
#define VECTOR_FLOAT_H_INCLUDED

// place the contents of the header here
class VectorFloat
{
public:
    // ...
    
// etc..    

#endif // VECTOR_FLOAT_H_INCLUDED 
Here is what my files looks like: I need to run the part2_test() in my main. Its so close to being finished, but I just cant seem to get it to work. I think its including the VectorFloat.h too many times and thus, is like "redefining" it which may cause the error.

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <cmath>
#include <iostream>
#include "Point.h"
#include "VectorFloat.h"
#include "part2_testing.h"


using namespace std;

void main()
{
....
....
part2_test();
}


VectorFloat.h
1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma
#ifndef VECTOR_FLOAT_H_INCLUDED
#define VECTOR_FLOAT_H_INCLUDED

class VectorFloat 
{
public:
...
...
...
}

#endif 


part2_testing.h
1
2
3
4
5
6
7
8
9
10
11
12
13
#pragma
#include <iostream>
#include "VectorFloat.h"

using namespace std;
void printVF(char const* name, const VectorFloat &vf) {
....
....}

void part2_test() {
....
....
}
What is that #pragma doing at the top of both your headers? Get rid of it.

And where is the include guard for part2_testing.h? Add an include guard.

If you are going to define functions in the header file, either declare them as inline, or give them internal linkage (or both):

1
2
3
4
//void printVF(char const* name, const VectorFloat &vf) {
inline void printVF(char const* name, const VectorFloat &vf) {
....
....}
I did that, but when I have guards on both the VectorFloat and the part2_testing headers, the function part2_test() in part2_testing.h is undefined.

Maybe theres something im missing, but tbh im not very good yet with c++, just a second year software eng student!

main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <cmath>
#include <iostream>
#include "Point.h"
#include "VectorFloat.h"
#include "part2_testing.h"


using namespace std;

void main()
{
....
....
part2_test();
}


VectorFloat.h
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef VECTOR_FLOAT_H_INCLUDED
#define VECTOR_FLOAT_H_INCLUDED

class VectorFloat 
{
public:
...
...
...
}

#endif 


part2_testing.h
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
#include <iostream>
#include "VectorFloat.h"
#ifndef VECTOR_FLOAT_H_INCLUDED
#define VECTOR_FLOAT_H_INCLUDED

using namespace std;

inline void printVF(char const* name, const VectorFloat &vf) {

	VectorFloat vf_a(vf.size());
	vf_a=vf;
	cout << "VectorFloat: " << name << endl;
	for (int i = 0; i < vf_a.size(); ++i) {
		cout << "  [" << i << "] :  " << vf_a[i] << endl;
	}
}

inline void part2_test() {

	VectorFloat vf1(3);
	VectorFloat vf2(3);

	vf1[0] = 1;
	vf1[1] = 2;
	vf1[2] = 3;

	vf2[0] = 3;
	vf2[1] = 2;
	vf2[2] = 1;

	printVF("vf1 start", vf1);
	printVF("vf2 start", vf2);
	printVF("vf1 + vf2", vf1 + vf2);
	vf1 += 4;
	printVF("vf1 after (vf1 += 4)", vf1);
	vf1 = vf2;
	printVF("vf1 after (vf1 = vf2)", vf1);
	cout << " dot product vf1 * vf2 = " << (vf1 * vf2)  << endl;

}
#endif 


Error:
1
2
3
4
5
6
7
1
1>  main.cpp
1>c:\users\cullan\documents\visual studio 2012\projects\assignment 1\assignment 1\main.cpp(50): error C3861: 'part2_test': identifier not found
1>  Generating Code...
1>  Compiling...
1>  VectorFloat.cpp
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Last edited on
Use different guards for different headers.

VectorFloat.h
1
2
3
4
5
6
7
8
#ifndef VECTOR_FLOAT_H_INCLUDED
#define VECTOR_FLOAT_H_INCLUDED

.......
.......
.......

#endif // VECTOR_FLOAT_H_INCLUDED 



part2_testing.h
1
2
3
4
5
6
7
8
#ifndef PART2_TESTING_H_INCLUDED
#define PART2_TESTING_H_INCLUDED

.......
.......
.......

#endif // PART2_TESTING_H_INCLUDED 



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
#include <iostream>
using namespace std;
#include "VectorFloat.h"
#ifndef PART2_TESTING_H_INCLUDED
#define PART2_TESTING_H_INCLUDED
//#pragma once


inline void printVF(char const* name, const VectorFloat &vf) {

	VectorFloat vf_a(vf.size());
	vf_a=vf;
	cout << "VectorFloat: " << name << endl;
	for (int i = 0; i < vf_a.size(); ++i) {
		cout << "  [" << i << "] :  " << vf_a[i] << endl;
	}
}

 inline void part2_test() {

	VectorFloat vf1(3);
	VectorFloat vf2(3);

	vf1[0] = 1;
	vf1[1] = 2;
	vf1[2] = 3;

	vf2[0] = 3;
	vf2[1] = 2;
	vf2[2] = 1;

	printVF("vf1 start", vf1);
	printVF("vf2 start", vf2);
	printVF("vf1 + vf2", vf1 + vf2);
	vf1 += 4;
	printVF("vf1 after (vf1 += 4)", vf1);
	vf1 = vf2;
	printVF("vf1 after (vf1 = vf2)", vf1);
	//cout << " dot product vf1 * vf2 = " << (vf1 * vf2)  << endl;

}
#endif 


nvm, i got it to work! thanks a bunch for everybody who helped, especially JLBorges :) I really appreciate it!
Last edited on
Topic archived. No new replies allowed.