Vector class question

Pages: 12
I've created my own class, "point2d", which i want to hold a vector array of x and y values. Then, in another class i make it a protected member function variable (if that's the correct terminology?)

Here is my 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
40
41
42
43
44
45
46
47
48
49
50
51
52

class point2d{

public:

  point2d(float x, float y) {mX=x; mY=y;} // constructor
  ~point2d() {}; // destructor

  float distance(point2d p);

  float mX,mY; // member variables

};


float point2d::distance(point2d p){

  float dist=0;
  float x=0, y=0;
  
  x=(mX-p.mX);
  y=(mY-p.mY);

  dist=sqrt((x*x)+(y*y));

  return dist;
}


class ShortestPath{

public:

	ShortestPath(vector<point2d> point_values, vector<int>& ord, int n, int c, int ck); // constructor
	~ShortestPath(void); // destructor

protected:

	vector<point2d> points;  // <------- seems to be the error!!

};

ShortestPath::ShortestPath(vector<point2d> point_values, vector<int>& ord, int n, int c, int ck){

	points = point_values;
	order = ord;
	NumberOfPoints = n;
	choose_k = ck;  // this is the user chosen k-nearest neighbours
	choose = c;

}



but when i try to compile, i get an error on the protected vector<point2d> points part.

I've left out all the other member functions etc. so that it might be easier to read.

Any thoughts?

What's the error say?
1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector(483) : error C2512: 'point2d::point2d' : no appropriate default constructor available
1> c:\program files (x86)\microsoft visual studio 9.0\vc\include\vector(480) : while compiling class template member function 'std::vector<_Ty>::vector(unsigned int)'
1> with
1> [
1> _Ty=point2d
1> ]
1> c:\users\jaz\documents\visual studio 2008\projects\shortestpath_class\shortestpath_class\shortestpath.h(61) : see reference to class template instantiation 'std::vector<_Ty>' being compiled
1> with
1> [
1> _Ty=point2d
1> ]
You declared a destructor for your point2d class, do you remember the rule of three for classes? You need to tell the app what to do if you are declaring a point2d object without arguments like line 39 does. In otherwords you need to define a default constructor.

EDIT: I meant to say you need to declare AND DEFINE a default constructor. Sorry about that.
Last edited on
Thanks for your help, and quick replies. It's much appreciated.

I'm pretty new to all this, so i've not heard of the rule of three (though i've just googled it). I'm not entirely sure what i need to do, though.

This is the default constructor, as i see it. I guess this is where i'm going wrong.
1
2
3
4
5
6
7
8

point2d::point2d(float x, float y) {

	mX=x;
	mY=y;

}





No, a default constructor is a constructor that takes no arguments. std::vector uses the default constructor of its stored objects.
filipe is right. You need to overload that constructor with a second one that does not take arguments, this infers that you will also need a member function that loads data into those variables.

EDIT: I didn't notice that mX and mY were public variables. I don't like doing it that way myself but technically you can use them directly instead of needing a member function to load them.
Last edited on
and how would one go about doing this?

i've created a new constructor:
1
2
3
4
5
6
7
8
9

point2d::point2d(){

//nothing in here

// so have removed mX = x, and mY = y

}


my code does actually now compile - but i can't imagine that what i've done is correct.
Why would this would be wrong? You're telling the program what to do when you order a new object with no parameters, which is nothing; you don't need to set additional memory aside, you don't need to import any data, you're pretty much all set.

NOTE: You do realize that you don't have to REPLACE your old constructor right? You can have both of them there at once. I only ask because you mentioned you were new at this.
Oh ok!! That's a bit of a nice surprise :)

No, i didn't know about not needing to replace the old constructor - thanks for the advice!
I suggest you initialize the variables to 0 in the default constructor. It's a good habit.
But i've removed all variables in the default constructor.......... so i'm not sure what you mean?
This:

1
2
point2d()
:mX(0), mY(0) { }
closed account (D80DSL3A)
Are you sure that line 39 is what the error pertains to?
I compiled a simplified version of your given code and had no problems.
I omitted the use of member variables not given in your code sample.
This builds fine:
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
class ShortestPath
{
public:
	ShortestPath(vector<point2d> point_values);//, vector<int>& ord, int n, int c, int ck); // constructor
	~ShortestPath(void); // destructor
        void showPts(void);// added to show that constructor is working
protected:
	vector<point2d> points;  // <-------are you sure this is causing the problem?
};

ShortestPath::ShortestPath(vector<point2d> point_values)//, vector<int>& ord, int n, int c, int ck)
{
	points = point_values;
//	order = ord;
//	NumberOfPoints = n;
//	choose_k = ck;  // this is the user chosen k-nearest neighbours
//	choose = c;
}

ShortestPath::~ShortestPath(void){}

void ShortestPath::showPts(void)
{
	for(vector<point2d>::iterator it = points.begin(); it != points.end(); ++it)
		cout << "(" << it->mX << ", " << it->mY << ") ";
	return;
}

int main(void)
{
	vector<point2d> pts;
	pts.push_back( point2d(1.0f, 1.1f) );// use of your constructor is OK here.
	pts.push_back( point2d(2.0f, 1.2f) );
	pts.push_back( point2d(3.0f, 1.3f) );
	ShortestPath path(pts);
        path.showPts();// show the points in the points vector
	cout << endl;
	return 0;
}


Output:

(1, 1.1) (2, 1.2) (3, 1.3)
Press any key to continue . . .
Last edited on
The code compiles if i have a default constructor, but it fails if it's not there...... as far as i'm aware, anyway.
closed account (D80DSL3A)
Perhaps the problem with the use of your old constructor was caused in some code you did not show us and NOT by the inclusion of a vector<point2d> in your ShortestPath class.

The code I posted shows that your original constructor is not causing a problem with the part of the code you gave.

This causes no problems:
1
2
vector<point2d> pts;
pts.push_back( point2d(1.0f, 1.1f) );

But this does:
pts.push_back( point2d() );
error C2512: 'point2d::point2d' : no appropriate default constructor available

Are you doing something like that elsewhere in your code?
Last edited on
@fun2code: Did you include a destructor in the "simplified" version of the OP's code? Because if you didn't then the compiler would have made a default constructor, destructor and copier for you. That is part of the Rule of Three I mentioned earlier.
Last edited on
closed account (D80DSL3A)
Yes. See line 20 in that post. It also appears that no default constructor was provided by the compiler. See the error I got just above.

EDIT: OP gave a prototype for the destructor in his code but no definition so I caught a link error when I tried to compile it. I then added a definition and all was good.
Last edited on
Ah ha. I see the error of my ways. fun2code, you are right (of course).

here is a snippet of the code which will not compile. if you remove the comments (which is the bit you did), and comment out my arraypoints bit, then i see why it now compiles. crafty. but, of course, logical.
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

class point2d{

public:

	//point2d(){ };// default constructor
	point2d(float x, float y);  // constructor
	~point2d(); // destructor

  float distance(point2d p);
  float mX,mY; // member variables

};

point2d::point2d(float x, float y) {

	mX=x;
	mY=y;

}

point2d::~point2d(void){

	// nothing in here, yet

}

float point2d::distance(point2d p){

  float dist=0;
  float x=0, y=0;
  
  x=(mX-p.mX);
  y=(mY-p.mY);

  dist=sqrt((x*x)+(y*y));

  return dist;
}


class ShortestPath
{
public:
	ShortestPath(vector<point2d> point_values);//, vector<int>& ord, int n, int c, int ck); // constructor
	~ShortestPath(void); // destructor
protected:
	vector<point2d> points;  // <-------are you sure this is causing the problem?
};

ShortestPath::ShortestPath(vector<point2d> point_values)//, vector<int>& ord, int n, int c, int ck)
{
	points = point_values;
//	order = ord;
//	NumberOfPoints = n;
//	choose_k = ck;  // this is the user chosen k-nearest neighbours
//	choose = c;
}

ShortestPath::~ShortestPath(void){}

int main(void)

{
	//vector<point2d> pts;
	//pts.push_back( point2d(1.0f, 1.1f) );// use of your constructor is OK here.
	//pts.push_back( point2d(2.0f, 1.2f) );
	//pts.push_back( point2d(3.0f, 1.3f) );
	//ShortestPath path(pts);

	int NumberOfPoints = 10;
	
	vector<point2d> arraypoints(NumberOfPoints);
	
	vector<int> order(NumberOfPoints);

		for (int i = 0; i < NumberOfPoints; i++){  // this loop calculates 2 sets of random numbers (x,y) and sets order to be 0,1,2,3....
			
			arraypoints[i].mX = 10 * rand() / float(RAND_MAX);
			arraypoints[i].mY = 10 * rand() / float(RAND_MAX);

			order[i] = i;
			
			cout << order[i] << "   " << arraypoints[i].mX << "    " << arraypoints[i].mY << endl;
		}

	cout << endl << endl;
	
	system("PAUSE");  // yes i know i shouldn't use this, but just for convenience at the minute
	return 0;
}

closed account (D80DSL3A)
Oh. So it's line 73 causing the problem then? Setting the initial capacity caused the need for a no-arg constructor.
Pages: 12