Vector of objects

Good evening once again,
I am facing a problem that i need to place different objects to vector. However they must be added at runtime and i cant add them before program is run. I have a default constructor, however values are random.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

int main()
{
	
	srand(static_cast<unsigned int>(time(0))); // set initial seed value to system clock
	rand(); // If using Visual Studio, discard first random value

	std::vector<Creature> pack(1000, Creature(BunnyGenerator::generateBunny())) ;

	for (int i = 0; i < pack.size(); i++)
		cout << pack[i] << endl;

	return 0;
}
Then populate the vector at runtime. Reserve capacity for 1000 objects or how many you need then push back random objects on the vector.
1
2
3
4
5
for (int i = 0; i < 25; i++)
		package.push_back(BunnyGenerator::generateBunny());

		for (unsigned int i = 0; i < package.size(); i++)
			cout << package[i] << endl;


This is what i came up with. However, i will need to increase one value of an object, and i can see that I am using an anonymous object and cant access it directly. How could i do that?
Adding random (different values) to a vector. Can also be other types too as long as it makes sense. Class types work too as long as they have a function which generates a "random" value for one of its members.

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
#include <iostream>
#include <vector>
#include <random>
#include <chrono>
#include <functional>

int main()
{
    constexpr unsigned short int SIZE = 1000;
    std::vector<unsigned short int> vec(SIZE);

    std::mt19937::result_type seed =
    std::chrono::high_resolution_clock::now().time_since_epoch().count();
    auto get_rand =
    std::bind(std::uniform_int_distribution<int>(0, 1000), std::mt19937(seed));

    for (unsigned short int &i : vec)
    {
        i = get_rand();
    }

    for (unsigned short int i : vec)
    {
        std::cout << i << '\n';
    }

    return 0;
}
Last edited on
It does add different values in the 2nd code that i posted. However, i will need to change one value and get one from an object that is randomly created but i dont know how. And I didnt really understand your program since all of the functions you wrote a new to me..
This is the entire program.

Creature.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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#pragma once
#include <string>
class Creature
{
public:
	enum BunnyName
	{
		TOM,
		ANTHONY,
		JAMES,
		LEBRON,
		PIKE,
		SPOKE,
		MAX_NAMES
	};
	enum BunnyColor
	{
		BROWN,
		BLACK,
		GREY,
		WHITE,
		SPOTTED,
		MAX_COLORS
	};

protected:
	BunnyName m_name;
	BunnyColor m_color;
	std::string m_sex;
	int m_age;
	 

public:
	Creature(BunnyName name = MAX_NAMES, BunnyColor color = MAX_COLORS, std::string sex = "M", int age = 0);
	~Creature();

	friend std::ostream& operator<<(std::ostream &out, Creature &creature);
	std::string getName();
	std::string getColor();
	int getAge() { return m_age; }
};

class BunnyGenerator
{
public:
	// Generate a random number between min and max (inclusive)
	// Assumes srand() has already been called
	static int getRandomNumber(int min, int max)
	{
		static const double fraction = 1.0 / (static_cast<double>(RAND_MAX) + 1.0);  
		return static_cast<int>(rand() * fraction * (max - min + 1) + min);
	}

	static Creature generateBunny()
	{
		Creature::BunnyColor color = static_cast<Creature::BunnyColor>(getRandomNumber(0, Creature::MAX_COLORS - 1));
		Creature::BunnyName  name = static_cast<Creature::BunnyName>(getRandomNumber(0, Creature::MAX_NAMES - 1));
		int age = m_age;
		static std::string s_sex[2] = { "M", "F" };

		return Creature(name,color, s_sex[getRandomNumber(0,1)], age);
	}
};


Creature.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
#include "stdafx.h"
#include "Creature.h"


Creature::Creature(BunnyName name, BunnyColor color, std::string sex, int age) : m_name(name), m_color(color),
 m_sex(sex), m_age(age)
{
}


Creature::~Creature()
{
}

std::ostream& operator<<(std::ostream &out, Creature &creature)
{
	out << creature.getName() << " " << creature.getColor() << " " << creature.m_sex << " " << creature.m_age;
	return out;
}

std::string Creature::getName()
{
	switch (m_name)
	{
	case TOM:		return "Tom";
	case ANTHONY:	return "Anthony";
	case JAMES:		return "James";
	case LEBRON:	return "Lebron";
	case PIKE:		return "Pike";
	case SPOKE:		return "Spoke";
	}

	return "???";
}

std::string Creature::getColor()
{
	switch (m_color)
	{
	case BROWN:		return "Brown";
	case BLACK:		return "Black";
	case GREY:		return "Grey";
	case WHITE:		return "White";
	case SPOTTED:	return "Spotted";
	}

	return "???";
}


Main.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
// Graduation v4.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Creature.h"
#include <vector>
#include <iostream>
#include <ctime>
using namespace std;


int main()
{
	
	srand(static_cast<unsigned int>(time(0))); // set initial seed value to system clock
	rand(); // If using Visual Studio, discard first random value

	std::vector<Creature> package;
	
	for (int i = 0; i < 25; i++)
		package.push_back(BunnyGenerator::generateBunny());

		for (unsigned int i = 0; i < package.size(); i++)
			cout << package[i] << endl;
	
	

	return 0;
}

Last edited on
boost didn't really answer your question.


1
2
3
4
5
6
7
8
9
10
11
12
package.reserve( 25 ); // pre-allocate memory in one go

for ( int i = 0; i < 25; ++i ) {
  Creature bunny = BunnyGenerator::generateBunny();
  // modify the bunny

  package.push_back( bunny );
}

for ( unsigned int i = 0; i < package.size(); ++i ) {
  cout << package[i] << endl;
}
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

	std::vector<Bunny> package;
	package.reserve(1000); // pre-allocate memory in one go
	int count = 0;
	int amount = 0;
	for (int i = 0; i < 5; i++)
	{
		Bunny bunny = BunnyGenerator::generateBunny();
		package.push_back(bunny);
		amount++;
		if (package[i].getSex() == "Male")
			count++;
	}
	while (amount < 50)
	{
		for (unsigned int i = 0; i < package.size(); i++)
			package[i].increaseAge();


		for (int i = 0; i < count; i++)
		{
			Bunny bunny = BunnyGenerator::generateBunny();
			package.push_back(bunny);
			amount++;
		}
		count = 0;
		for (unsigned int i = 0; i < package.size(); i++)
		{
			if (package[i].getSex() == "Male")
				count++;
		}

	}
	

	for (vector<Bunny>::iterator it = package.begin(); it != package.end(); it++)
		cout << *it << endl;


I need to be able to create an object that would delete himself from the vector once package.getAge() is 10 how could i do that? would it work with pop_back?


EDIT: I tried erase() however faced some difficulties..
Last edited on
Use remove_if and erase. See http://www.cplusplus.com/reference/algorithm/remove_if/

1
2
3
4
5
6
7
// range-based for loop syntax:
for ( auto & bunny : package ) bunny.increaseAge();

// cull the old: with remove-erase idiom and lambda function
package.erase( std::remove_if( package.begin(), package.end(),
                               []( auto b ) { return 10 <= b.getAge(); } ),
               package.end() );



PS. Why do you have a separate amount? The package has size().


See also: http://www.cplusplus.com/reference/algorithm/count_if/
count = std::count_if( package.begin(), package.end(), []( auto b ) { return "Male" == b.getSex(); } );
I was testing my program and had amount for testing i do realize that, thanks for pointing that out tho!
Topic archived. No new replies allowed.