Problems Declaring a Vector in a Class

Started by
6 comments, last by GameDev.net 18 years, 11 months ago
Hey, I've been working on a C++ program (to get some experience with programing in general) for a while now that requires two dimensional vectors as class elements. But I've been having problems initalizing the vectors of integer vectors in the class constructor (or anywhere else in the class). I was able to get this code past the first stage of the compiling process (compiler being MS Visual Studio.NET 2003):

#include <iostream>
#include <string>
#include <vector>

using namespace std;

main()
{
	char stop = 'd';
	typedef vector<int> VecInt;
	

	class lVector
	{
	private:
		vector<VecInt> L;
		int Lp1;
		int Lp2;
		
	public:

		lVector(int p1, int p2)
		{
			Lp1 = p1; 
			Lp2 = p2;
			vector<int> a(Lp1);
			vector<VecInt> L(Lp2, a);    
		}

		void get2dVector()
		{
			for(int i = 0; i < Lp1; i++)
				for(int j = 0; j < Lp2; j++)
				{
					L[j] = 2;
					cout<<"L["<<j<<"]["<<i<<"] is: "<<L[j]<<endl;
				}
		}
	};

	lVector veci(4, 4);
	veci.get2dVector();
	cin>>stop; //so i can see the output screen, and see if it works
}

but then as the output screen appears everything crashes and I'm put into debug mode and I am directed to this code from the vector file:

iterator begin()
		{	// return iterator for beginning of mutable sequence
		return (iterator(_Myfirst));
		}

Any suggestions/comments? Does anyone know how to appease the compiler god?
Advertisement
I havn't looked very closely but at first glace one notices that in your constructor you have the line vector L(Lp2, a);

This won't initialise the member variable, it will create a new local variable within the scope of the constructor.
If I understand you correctly you want an initialisation list...
class newclass{     private:     lVector;      public:     newclass(int x, int y) : lVector(x, y)     {     }};
vector<VecInt> L(Lp2, a);


As mentioned, this creates a temporary variable within the ctor, which has nothing to do with your member variable. Try this instead:

L = vector<VecInt>(Lp2, a);


However, you really should do this initialization with initializer lists:

lVector(int p1, int p2) : Lp1(p1), Lp2(p2), L(Lp2, vector<int>(Lp1)) {}


Here a temporary vector is created as a "prototype" for the inner dimension, and gets copied several times for initializing the nested vector. The syntax of the initializer items is straightforward: follow each member to be initialized with a constructor argument list in brackets (or in the case of primitives, an expression to evaluate - the primitives are treated as if they were POD structs with the copy ctor being used, basically). Note that this is an optimization where possible, because it specifies how the members will be constructed, whereas such construction happens anyway before any code inside the ctor body - assigning to a member in the ctor simply overwrites a default-initialized value. (Unless of course the compiler is smart enough to optimize it away...) Also note that because of the scoping rules, you can do this sort of thing:

myThing(type member): member(member) {}// in "member(member)", the 'member' outside the brackets must necessarily be// this->member, because other variables can't be referenced there - you can// only initialize things that are part of the object being initialized. But// inside the brackets, the scoping is the same as inside the ctor body.

Does std::vector have the correct copy constructors and whatnot that std::vector requires of its data types?

I know people hate it when I say this, but I would just implement it your self. It is far less painful then trying to get canned objects to do what you want.

That said…
If the above is true (std::vector does not have the correct copy constructor, this should show up as one of your errors (worded differently of course)), then one thing you could do is derive a class from std::vector and add in the needed functions. Or create a class that has an std::vector as a member, and implement in that class the necessary fuctions (which edit the member). The first way is cleaner (and better coding), the second is more straight forward but will make for some messy code down the road.

Good luck
Um, I hate to say this, but I haven't understood most of what you guys have posted. All I can understand is that "L(Lp2, a)" creates a local variable in the constructor. Apparently I'm suffering from too little knowledge. Also I'm not sure what it is that I need to learn, is it copy constructors? Vectors in general? Or something else? Anyway, I replaced this code:
lVector(int p1, int p2)		{			Lp1 = p1; 			Lp2 = p2;			vector<int> a(Lp1);			vector<VecInt> L(Lp2, a);    		}


with the member initialization list (as suggested by Zahlman):
lVector(int p1, int p2) : Lp1(p1), Lp2(p2), L(Lp2, vector<int>(Lp1)) {}

Unfortunately this also causes a crash and places me in the vector file once again, but at a different place:
void _Xlen() const		{	// report a length_error		_THROW(length_error, "vector<T> too long");		}

So I ask two questions...One, what should I look up so I can understand your previous posts. And two, what do you think caused this crash (that is if you think I can understand it ;) ).
Quote:Original post by Anonymous Poster
Um, I hate to say this, but I haven't understood most of what you guys have posted. All I can understand is that "L(Lp2, a)" creates a local variable in the constructor. Apparently I'm suffering from too little knowledge. Also I'm not sure what it is that I need to learn, is it copy constructors? Vectors in general? Or something else?


Copy constructors in general shouldn't really be relevant here; std::vector does what it needs to for this part, and CyberFox basically is trolling here.

Quote:Unfortunately this also causes a crash and places me in the vector file once again, but at a different place:

So I ask two questions...One, what should I look up so I can understand your previous posts.


The C++ FAQ Lite would be a good place to start. There's also a link hidden in there to "The correct C++ Tutorial". Read as much of both as you can afford time for.

Quote:And two, what do you think caused this crash (that is if you think I can understand it ;) ).


I did some debugging and found the problem: The initializer list I gave you isn't in the same order as the members listed in the class. The members are initialized in the order they're specified for the class data, regardless of how they're ordered in the initializer list. Thus the L vector gets created while Lp1 and Lp2 are still uninitialized. (Under GCC, compiling with -Wall produces an warning for a mismatch in the ordering.)

To fix, either rearrange the data members to match the data list, or (probably better) use p1 and p2 for initializing L (rather than Lp1 and Lp2).

What is 'l' supposed to stand for anyway? :)
What does L stand for? ....ABSOLUTELY...NOTHING. This program is just a programming exercise, so the variable names have no meaning really. Oh, and thanks for all the info, I really appricate it.

This topic is closed to new replies.

Advertisement