Can vectors hold objects that contain vectors?

My searches would suggest no (something about a vector has to know the size of the objects it contains and since vectors can change, that means it doesn't work).

In short, I'm wanting to create an vector that contains objects that have vectors. The only thing that I can think of that would work would be instead of my objects having vectors, it would have an array that would be appropriately sized to be sure that it could hold whatever was put in it. But that seems somewhat sloppy (maybe my entire approach to this is sloppy but that's how you learn :) ). If I have to do it I will but I'd like to get more information if I can.
closed account (N36fSL3A)
Yes they can.
a vector has to know the size of the objects it contains

It has to know the size of the individual objects it holds for memory allocation purposes, but the actual storage is done using a pointer data member (so it can be resized dynamically.)

And (for a given architecture) the size of a pointer is the same whatever type is pointed to. This means that the size of the vector itself is the same whatever it holds e.g.

(results for a 32-bit system; see code below)

sizeof(int) = 4
sizeof(ivec) = 20

sizeof(char) = 1
sizeof(cvec) = 20

sizeof(Biggish) = 4100
sizeof(bvec) = 20


Therefore, as the size of a vector is known at compile time, you can nest them as deeply as you like.

1
2
// ANSI C++03
vector<vector<vector<vector<vector<vector<int> > > > > > vec6deep;


1
2
// ANSI C++11
vector<vector<vector<vector<vector<vector<int>>>>>> vec6deep;


And also that they can be used as class members, as their size is known (though not the size of the storage they use.)

Andy

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
#include <iostream>
#include <vector>
using namespace std;

struct Biggish {
	int used;
	int data[1024];
};

int main() {
	vector<int> ivec;
	cout << "sizeof(int) = " << sizeof(int) << endl;
	cout << "sizeof(ivec) = " << sizeof(ivec) << endl;
	cout << endl;

	vector<char> cvec;
	cout << "sizeof(char) = " << sizeof(char) << endl;
	cout << "sizeof(cvec) = " << sizeof(cvec) << endl;
	cout << endl;

	vector<Biggish> bvec;
	cout << "sizeof(Biggish) = " << sizeof(Biggish) << endl;
	cout << "sizeof(bvec) = " << sizeof(bvec) << endl;
	cout << endl;

	return 0;
}
Last edited on
Andy, you sort of know what I am working on so hopefully my explanation of what I am doing will make sense :).

I've created a character class that is basically a collection of two wstrings.

Then I've created an orthography class that holds a string for the orthography name and a vector that holds the character class objects.

Then what I'm trying to do in my program is create a vector that holds orthography objects. Then once I get that working, I'll work on a way to store the objects to a file so they can be saved and retrieved. I initially thought to go the route of using the map class for this but after toying around with it a bit, it wouldn't work because there is no way for there to be totally unique keys whether they are based on one wstring or the other.

I think I have the rough code of my character and orthography classes lined out and I'm sure they will need a few more tweaks and additions. I'll post them below. Where I'm running into trouble is trying to create a new orthography object and put it into the vector. I have a window that takes in text and uses it to create the orthography object by using the text for the object's name.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
case IDB_SUBMIT_ORTHOGRAPHY:

			// Get the text from the input textbox
			GetWindowTextW(hOrthographyInput, input, 256);

			// Make sure there isn't already an orthography with this name
			for (int i = 0; i < g_Orthographies.size(); i++)
			{
				if (input == g_Orthographies[i].GetName())
					// TODO: ERROR CODE!!!
					return true;
			}

			// Resize the vector array to accomodate the new orthography
			g_Orthographies.resize(g_Orthographies.size() + 1);

			// Create a new orthography and put it in the vector array
			// Having trouble with the line below...syntax is wrong somehow
			g_Orthographies[g_Orthographies.size() - 1] = new Orthography(input);

			return true;


And here is my CharacterMatch class header code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class CharacterMatch
{
public:
	// Constructor(s)/Destructor
	CharacterMatch();
	CharacterMatch(wstring name, wstring wInput, wstring wOutput);
	~CharacterMatch();

	// Accessor functions
	wstring GetName();
	wstring GetInput();
	wstring GetOutput();

private:
	// Members
	wstring m_Name;
	wstring m_Input;
	wstring m_Output;
};


And here is my orthography header and cpp code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Orthography
{
public:
	// Constructor(s)/Destructor
	Orthography();
	Orthography(wstring name);
	~Orthography();

	// Accessor functions
	wstring GetName();
	int GetNumberOfCharacterMatches();
	vector<CharacterMatch> GetCharacterMatches();

	// Class functions
	void AddCharacterMatch(CharacterMatch match);

private:
	// Members
	wstring m_Name;
	int m_NumberOfCharacterMatches;

	vector<CharacterMatch> m_CharacterMatches;
};


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
// Constructor
Orthography::Orthography()
{
	
}

Orthography::Orthography(wstring name)
{
	m_Name = name;
}

// Destructor
Orthography::~Orthography()
{

}


// Accessor Functions
wstring Orthography::GetName()
{
	return m_Name;
}

int Orthography::GetNumberOfCharacterMatches()
{
	return m_NumberOfCharacterMatches;
}

vector<CharacterMatch> Orthography::GetCharacterMatches()
{
	return m_CharacterMatches;
}



void Orthography::AddCharacterMatch(CharacterMatch match)
{
	// TODO: Create match comparison to avoid duplicate entries.

	// Increase the number of character matches
	m_NumberOfCharacterMatches++;

	// Resize the vector array
	m_CharacterMatches.resize(m_NumberOfCharacterMatches);

	// Put the new character match into the orthography
	m_CharacterMatches[m_NumberOfCharacterMatches - 1] = match;
}


Bear in mind that I haven't been able to test this yet so there may be more issues that need to be addressed.
I have nothing much to say about you code, except:

- lines 15 and 19 of the IDB_SUBMIT_ORTHOGRAPHY handler should be just one: you are basically reimplementing vector::push_back()
http://www.cplusplus.com/reference/vector/vector/push_back/

Similarly for lines 45 and 48 of AddCharacterMatch()

- you should stop keeping track of the size of vectors; they know their own size. So the Orthography class need to lose m_NumberOfCharacterMatches. Then recode

1
2
3
4
int Orthography::GetNumberOfCharacterMatches()
{
	return m_CharacterMatches.size();
}


(though it's better to use size_t (rather than int) for the sizes of things -- vector::size returns a size_t, for example.

You could also lose a bit of vertical space (but not too much.)

There are a few other issues, but they are less of a deal.

Andy
Yea, keeping track of things comes from when I was learning to program. I keep forgetting that the new things I learn usually have quite a bit to them (IE knowing their own size or even something like push_back). Which is why I tend to do things the hard way.

What would the syntax be to dynamically create a new orthography and then add it to the vector via push_back in one line? I'm having other issues that I need to fix before I can test this but I'd like to throw my code at you to see what you think. Especially since I won't be able to fix the issue for a while due to the holiday today. I get no red lines with this but it just doesn't "feel right." I'd thought that it would need to be a dynamically created object but when I try using "new" then I get the red lines.

g_Orthographies.push_back(Orthography(input));
Assuming your vector stores Orthography* pointers, then

1
2
3
4
5
6
			// Resize the vector array to accomodate the new orthography
			g_Orthographies.resize(g_Orthographies.size() + 1);

			// Create a new orthography and put it in the vector array
			// Having trouble with the line below...syntax is wrong somehow
			g_Orthographies[g_Orthographies.size() - 1] = new Orthography(input);


becomes

1
2
			// Create a new orthography and put it in the vector array
			g_Orthographies.push_back(new Orthography(input));


Using new just like you were before.

Of course, the size of the vector increases by one, which is why it's better not to keep a separate (unecessary) count. Here, that count would need to be incremented, too.

I'd like to throw my code at you

Just so you know, I don't have enough time for anything big, when it comes to code. Just snippets.

Andy
Topic archived. No new replies allowed.