void class Arrays Sequential and Binary Search Using - c++

I'm currently at my wits end trying to figure out how to do this, and was hoping someone could help.
The objectives the assignment is to:
Display the original sorted array of student records.
Display the sequential search result of student records.
Display the binary search result of student records.
The Full Instructions are:
a. Create three array of 12+ students records including ID’s, student names, and
the corresponding e-mail address’,– student ID’s are sorted in order. (No sort program needed for now.)
b. Sequential Search five ID’s which are from the sorted array and a 6th ID which is not from the array.
c. Binary Search five ID’s which are from the sorted array and a 6th ID which is not from the array.
d. Execution and output:
Display the original sorted array of student records.
Display the sequential search result of student records.
Display the binary search result of student records.
Any Help would be greatly appreciated
#include <iostream>
#include <iomanip>
#include <string>
#include <cmath>
#include <algorithm>
using namespace std;
struct Student {
string name;
int stuID;
string email;
};
// Show the student information
void showAllInfo(Student *studentArray, int stuCount) {
cout << "Student Info: "<<endl <<endl<<
"\t\tStudent Name"<<"\t\tStudent ID"<<"\t\tStudent Email"<<endl<<endl ;
for (int i = 0; i < stuCount; i++)
{
cout<<"\t\t"<< studentArray[i].name<<"\t\t"<<studentArray[i].stuID<<"\t\t\t"<< studentArray[i].email<<endl;
}
cout << endl;
}
//Sort out the arrays for the student information
void firstArray()
{
Student studentArray[12];
studentArray[0].name = "Bob McBoberston";
studentArray[0].stuID = 00;
studentArray[0].email = "BMcboberts#txstate.edu";
studentArray[1].name = "Shelby Donald";
studentArray[1].stuID = 1;
studentArray[1].email = "SDonald#txstate.edu";
studentArray[2].name = "Ronald Mcdonald";
studentArray[2].stuID = 2;
studentArray[2].email = "RMcdonald#txstate.edu";
studentArray[3].name = "Dick Cheney";
studentArray[3].stuID = 3;
studentArray[3].email = "DCheney#txstate.edu";
studentArray[4].name= "Ben Dover";
studentArray[4].stuID=4;
studentArray[4].email="BDover#txstate.edu";
studentArray[5].name="Ash Katchum";
studentArray[5].stuID=5;
studentArray[5].email="AKatchum#txstate.edu";
studentArray[6].name="Brock Whatever";
studentArray[6].stuID=6;
studentArray[6].email="BWhatevr#txstate.edu";
studentArray[7].name="Yugi Oh";
studentArray[7].stuID=7;
studentArray[7].email="YugiOh#txstate.edu";
studentArray[8].name="Johnny Bravo";
studentArray[8].stuID=8;
studentArray[8].email="JBravo#txstate.edu";
studentArray[9].name="Tom N. Jerry";
studentArray[9].stuID=9;
studentArray[9].email="Tnjerry#txstate.edu";
studentArray[10].name="Fred Flinstone";
studentArray[10].stuID=10;
studentArray[10].email="FFlinstone#emial.com";
studentArray[11].name="Son Goku";
studentArray[11].stuID=11;
studentArray[11].email="sGoku#txstate.edu";
studentArray[12].name="Johnny Test";
studentArray[12].stuID=12;
studentArray[12].email="JTest#txstate.edu";
}
void secondArray()
{
Student studentArray2[12];
studentArray2[0].name = "Rick Sanchez";
studentArray2[0].stuID = 13;
studentArray2[0].email = "RSanchez#txstate.edu";
studentArray2[1].name="Morty Smith";
studentArray2[1].stuID = 14;
studentArray2[1].email = "MSmith#txstate.edu";
studentArray2[2].name = "Summer Smith";
studentArray2[2].stuID = 15;
studentArray2[2].email = "SSmith#txstate.edu";
studentArray2[3].name = "Jerry Smith";
studentArray2[3].stuID = 16;
studentArray2[3].email = "JSmith#txstate.edu";
studentArray2[4].name="Mr. Meeseeks";
studentArray2[4].stuID=17;
studentArray2[4].email="MMeeseeks#txstate.edu";
studentArray2[5].name="Mr. PoopyButtHole";
studentArray2[5].stuID=18;
studentArray2[5].email="MPoopyButt#txstate.edu";
studentArray2[6].name="Tiny Rick";
studentArray2[6].stuID=19;
studentArray2[6].email="TRick#txstate.edu";
studentArray2[7].name="Pickle Rick";
studentArray2[7].stuID=20;
studentArray2[7].email="PRick#txstate.edu";
studentArray2[8].name="Beth Smith";
studentArray2[8].stuID=21;
studentArray2[8].email="BSmith#txstate.edu";
studentArray2[9].name="Bird Person";
studentArray2[9].stuID=22;
studentArray2[9].email="BmPerson#txstate.edu";
studentArray2[10].name="Squanchy";
studentArray2[10].stuID=23;
studentArray2[10].email="Squanchy#txstate.edu";
studentArray2[11].name="King Flippy Nips";
studentArray2[11].stuID=24;
studentArray2[11].email="KFlippyNipa#txstate.edu";
studentArray2[12].name="Mr> Goldenfold";
studentArray2[12].stuID=25;
studentArray2[12].email="MGoldenfold#txstate.edu";
}
void thirdArray()
{
Student studentArray3[13];
studentArray3[0].name = "Santa Claus";
studentArray3[0].stuID = 26;
studentArray3[0].email = "SClause#txstate.edu";
studentArray3[1].name = "Jason Riha";
studentArray3[1].stuID = 27;
studentArray3[1].email = "JRiha#txstate.edu";
studentArray3[2].name = "B-Rad Cragg";
studentArray3[2].stuID = 28;
studentArray3[2].email = "BRad#txstate.edu";
studentArray3[3].name="Roger Legrand";
studentArray3[3].stuID = 29;
studentArray3[3].email = "RLegrand#txstate.edu";
studentArray3[4].name="David De La O";
studentArray3[4].stuID=30;
studentArray3[4].email= "DDelao#txstate.edu";
studentArray3[5].name="Ian Sporn";
studentArray3[5].stuID=31;
studentArray3[5].email="ISporn#txstate.edu";
studentArray3[6].name="Morgan Taylor";
studentArray3[6].stuID=32;
studentArray3[6].email="Mytaylor#txstate.edu";
studentArray3[7].name="Sam Huggins";
studentArray3[7].stuID=33;
studentArray3[7].email="SHuggins#txstate.edu";
studentArray3[8].name="Shaun Huggins";
studentArray3[8].stuID=34;
studentArray3[8].email="ShuHuggins#txstate.edu";
studentArray3[9].name="Serena Huggins";
studentArray3[9].stuID=35;
studentArray3[9].email="SerHuggins#txstate.edu";
studentArray3[10].name="Kylie Parziale";
studentArray3[10].stuID=36;
studentArray3[10].email="KParziale#txstate.edu";
studentArray3[11].name="Jimmy Fallon";
studentArray3[11].stuID=37;
studentArray3[11].email="JFallon#txstate.edu";
studentArray3[12].name="Tom Goat Brady";
studentArray3[12].stuID=38;
studentArray3[12].email="TGBrady#txstate.edu";
studentArray3[13].name="Harry Giblets";
studentArray3[13].stuID=39;
studentArray3[13].email="HGiblets#txstate.edu";
}
int main() {
int stuCount = 39;
firstArray();
secondArray();
thirdArray();
showAllInfo(studentArray,stuCount);
return 0;
}

So you have a few problems. The first is that your arrays are declared inside the functions you've written, so no other code is going to be able to access them. You should declare your arrays inside the main function so that they can be passed as parameters to other functions. If you don't know how to pass an array as a parameter then the rest of this assignment is going to be difficult for you.
Anyway lets start like this, you don't need to write function to set up your arrays, you can do it directly in main, like this
int main()
{
Student firstArray[12] = {
{ "Bob McBoberston", 0, "BMcboberts#txstate.edu" },
...
};
Student secondArray[12] = {
...
};
Student thirdArray[12] = {
...
};
...
}
Now that the arrays are set up you need to write a function to do the sequential search (binary search is more complex, so leave that one for now).
Think about what parameters a function needs and what return value it has. This is always the first step when writing a function, but it's also one that many newbies struggle with.
In the case a sequential search function it needs to know 1) which array is it going to search, 2) how big that array is, 3) what id you are searching for. These are the parameters. It seems reasonable for the function to return the index in the array of the person it's found, or a special value -1 if it doesn't find the id. That's not the only way to do it, but it'll do for now. So putting that together we have
// look for 'id' in 'array' and returns the index if found or -1 if not found
int sequential_search(Person array[], int array_size, int id)
{
...
}
In your main function you would use this function something like this
int main()
{
...
// look for person with id 5
int id = 5;
int index = sequential_search(firstArray, 12, id);
if (index == -1)
cout << "ID " << id << " not found\n";
else
cout << "ID " << id << " is " << firstArray[index].name << "\n";
}
Get the idea? Hopefully this gives you a start. You can do the rest, and ask again if you get into difficulties.

Related

Vector Isn't Creating Multiple Class Objects

I have a vector that stores multiple class objects for later access. This way my program can create new objects during runtime. This is done like so:
vector<Person> peopleVector;
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
This function should print out each objects "name" every time the code runs (it's a function that runs multiple times). However, when I run this, somehow the vector does not increase in size. If you add cout << peopleVector.size(); to that code, you will find that each time it runs, it gets one (obviously assuming you also have the class code which I have below).
I'm curious why I can't create multiple objects in the class.
Class.h
#pragma once
#include <iostream>
using namespace std;
class Person {
public:
Person(string personName, int personAge);
string name;
int age;
};
Person::Person(string personName, int personAge) {
name = personName;
age = personAge;
}
Main.cpp
#include "Class.h"
#include <random>
int main() {
// Necessary for random numbers
srand(time(0));
string name = names[rand() % 82]; // Array with a lot of names
int age = 4 + (rand() % 95);
}
// Create a new person
void newPerson(string name, int age) {
vector<Person> peopleVector;
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
}
Just FYI those #includes might be a little bit off because I took that code out of a large section that had like 15 includes.
You are creating an empty vector each time you call your newPerson() function, and then you add a single person to it.
You then display the contents of that vector. What else can it contain, other than the single person that you added?
Problem
Every time a function runs, all local variables inside the function are re-created in their default state. That means that every time you call newPerson, it just recreates peopleVector.
Solution
There are two solutions:
Have newPerson take a reference to a vector, and add it on to that
make peopleVector static, so that it isn't re-initialized every time
First solution:
// Create a new person; add it to peopleVector
// The function takes a reference to the vector you want to add it to
void newPerson(string name, int age, vector<Person>& peopleVector) {
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
}
Second solution: mark peopleVector as static
// create a new person; add it to peopleVector
void newPerson(string name, int age) {
// Marking peopleVector as static prevents it from being re-initialized
static vector<Person> peopleVector;
peopleVector.push_back(Person(name, age));
for (int i = 0; i < peopleVector.size(); i++) {
cout << peopleVector[i].name << endl;
}
}

How can I store predefined values sorted according to date in C++?

I want to store predefined(hardcoded) values in person object and display it on the screen with date sorted.How can I achieve that?
Here are the problem and my code.
A society keeps a list of members and uses a program to store the list.For each member, the following information is recorded
membership number
surname
the first name
the date that the person joined the society
whether or not they are still a member
The program is required to offer three options
1) Enter the details of the member(either current or past member).Members may be entered in any order.You can assume the membership number is available from some existing list so just needs to be entered into the program along with other data.
2) Prompt for the current date and produce as output a list of people who have been a member for at least 10years(and still a member currently)The list should be in order of date joined and split up according to how long they have been a member(50+years,40+years etc)If there is more than one person who joined on the same day, they should be given in alphabetical order of surname and if they have same surname, first name.The list should produce by sorting the set of members into the order required.
3)Prompt for membership number and mark the person's membership as not current.
Output should look something like this
Long-standing members at 20/02/2012
50+years
mem no date joined name
432 21/07/1963 Xerxes Smith
3103 20/02/1968 Aloysius Baker
40+years
mem no. date joined name
4934 21/02/1968 Hermione Turner
0123 08/06/1975 Bartholomew Wright
1498 08/06/1975 Ermintrude Wright
30+year
—————————————————————————————————
I'm only giving you bubble sort.
#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;
class person
{
public:
person(string doj)
{
memset(&m_doj, 0, sizeof(tm));
std::istringstream ssDate(doj);
ssDate >> get_time(&m_doj, "%d/%m/%Y");
}
tm m_doj;
bool operator> (person &person2)
{
return mktime(&m_doj) > mktime(&person2.m_doj);
}
void output()
{
cout << put_time(&m_doj, "%d/%m/%Y") << "\n";
}
};
void swap(person *xp, person *yp)
{
person temp = *xp;
*xp = *yp;
*yp = temp;
}
void bubbleSort(person arr[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++)
// Last i elements are already in place
for (j = 0; j < n - i - 1; j++)
if (arr[j] > arr[j + 1])
swap(&arr[j], &arr[j + 1]);
}
void main()
{
person people[5] = { person("22/02/2012"), person("21/03/2012"), person("21/02/2018"), person("21/02/1969"), person("20/02/2012") };
bubbleSort(people, 5);
for (int i = 0; i < 5; ++i)
{
people[i].output();
}
}

Getline() and cin manipulate dynamic array

I'm totally lost and confused and could use some help.
I'm currently working on a small command line-based game. For this I wrote a class Inventory, dynamically creating an array of invSpace-objects, each space representing a pair of a pointer to an Item (another class of mine) and a integer, depicting a quantity. Here's the code:
class invSpace {
public:
Item *item;
int quantity;
invSpace() {
item = NULL;
quantity = 0;
}
};
class Inventory {
private:
invSpace* spaces = NULL;
size_t size;
public:
int free_space() {
int free = 0;
for (int i = 0; i < size; i++) {
if (spaces[i].item == NULL) {
free++;
}
}
return free;
}
Inventory() {}
Inventory(size_t new_size) {
size = new_size;
spaces = new invSpace[size];
for (int i = 0; i < size; i++) { //I know this is obsolete because
spaces[i].item = NULL; //of the invSpace constructor, I
spaces[i].quantity = 0; //just did this for testing
}
~Inventory() {
delete[] spaces;
}
invSpace& operator[](int index) {
return spaces[index];
}
};
There are some more methods in this class, like for adding, deleting and searching for items, but those don't matter now. So this is basically just a simple array within one object, dynamically allocating memory in the constructor and with some extra methods. After being created, the array contains zero elements, or Items, so the free_space() method should return the size of the array. But it doesn't. It returns about half of the size.
My first thought was that something went wrong with the allocation. But at a second glance I noticed that the Inventory is totally fine directly after being created; with exactly as many spaces as requested, all of them set to item=NULL/quantity=0. But after a call of getline() at the start of main() that scans user input and saves it to a string for further analyzing, some spaces get filled with random addresses and integers.
Even stranger, with each new call of getline() some spaces are freed, some others filled. As far as my debugging, experimenting and testing goes, none of these addresses belong to any variable in my program, they are just plain random. Also, at no point is there be any interference with the Inventory and the getline() function or the string it returns. In fact, after being created, no part of this object is used anywhere in the code beside the free_space() method. What's even stranger is that spaces in the Inventory class is marked private, so a method is required to meddle with this pointer/array (or so I would expect).
This problem occurs with getline() and cin but not with any of C's <stdio.h> input stream functions. Using malloc() instead of new[] makes no difference. Of course, I could use something like scanf() for the reading from the console. Still, I just want to know why all these things happen. I have absolutely no idea.
Thanks in advance for every answer!
EDIT:
I narrowed the whole code so that it still produces the same error, also changed free_space() so that it prints adress and integer if present:
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Item {
public:
static map<string, Item*> itemlist;
string name;
string description;
Item() {}
Item(const string new_name, const string new_description) {
name = new_name;
description = new_description;
itemlist.insert(pair<string, Item*> (name, this));
}
};
map<string, Item*> Item::itemlist;
/*The more Items are declared, the more random adresses appear in the
inventory*/
Item item01("sword", "A sharp and deadly weapon.");
Item item02("shield", "This will protect you. To a certain extent.");
Item item03("stick", "What is this for exactly?");
Item item04("bottle of water", "A bottle full of refreshing spring water.");
class invSpace {
public:
Item *item;
int quantity;
invSpace() {
item = NULL;
quantity = 0;
}
};
class Inventory {
private:
invSpace* spaces = NULL;
size_t size;
public:
int free_space() {
int free = 0;
for (int i = 0; i < size; i++) {
if (spaces[i].item == NULL) {
free++;
cout << i << " = free" << endl;
}
else {
cout << spaces[i].item << " / " << spaces[i].quantity << endl;
}
}
return free;
}
Inventory() {}
Inventory(size_t new_size) {
size = new_size;
spaces = new invSpace[size];
for (int i = 0; i < size; i++) {
spaces[i].item = NULL;
spaces[i].quantity = 0;
}
}
~Inventory() {
delete[] spaces;
}
};
class Player {
public:
string name;
Inventory inventory;
Player(const string new_name) {
inventory = Inventory(40);
name = new_name;
}
};
Player player("Me");
int main() {
string input;
//Inventory inventory(40); //no error when declared outside the Player class
while (1) {
cout << "\n>> ";
getline(cin, input);
if (input == "x") {
break;
}
else {
player.inventory.free_space();
}
}
}
Some things I noticed: No error occurs if the inventory isn't part of a Player-object. If it is but no Items are declared only the first inventory space receives a random adress (and int value) after the first call of getline().
The more Items there are, the more random adresses I get, it seems...

Declaring my member function parameters/arguments

class Seller
{
private:
float salestotal; // run total of sales in dollars
int lapTopSold; // running total of lap top computers sold
int deskTopSold; // running total of desk top computers sold
int tabletSold; // running total of tablet computers sold
string name; // name of the seller
Seller::Seller(string newname)
{
name = newname;
salestotal = 0.0;
lapTopSold = 0;
deskTopSold = 0;
tabletSold = 0;
}
bool Seller::SellerHasName ( string nameToSearch )
{
if(name == nameToSearch)
return true;
else
return false;
}
class SellerList
{
private:
int num; // current number of salespeople in the list
Seller salespeople[MAX_SELLERS];
public:
// default constructor to make an empty list
SellerList()
{
num = 0;
}
// member functions
// If a salesperson with thisname is in the SellerList, this
// function returns the associated index; otherwise, return NOT_FOUND.
// Params: in
int Find ( string thisName );
void Add(string sellerName);
void Output(string sellerName);
};
int SellerList::Find(string thisName)
{
for(int i = 0; i < MAX_SELLERS; i++)
if(salespeople[i].SellerHasName(thisName))
return i;
return NOT_FOUND;
}
// Add a salesperson to the salespeople list IF the list is not full
// and if the list doesn't already contain the same name.
void SellerList::Add(string sellerName)
{
Seller(sellerName);
num++;
}
I have some issues with the parameters in my functions in my SellerList class. I want to add someone to the salespeople array so I have a record of all my sellers... Bob, Pam, Tim, etc... My constructor Seller(sellerName) creates a Seller with name sellerName.
How do I add this Seller to the Salespeople array and have capability of a way to pull the data back out and use it in more functions such as a Update function, or an output function?
MAX_SELLERS = 10.... I guess my issue is not knowing whether to use parameters of only
Add(string) or Add(Seller, string). Any help would be appreciated.
Not reinvent the wheel. Choose the container appropiate to your problem. In this case, because you are referencing/searching Sellers by a std::string, I suggest you to use a hash table like std::unordered_map (Or std::map search tree if you don't have access to C++11):
int main()
{
std::unordered_map<Seller> sellers;
//Add example:
sellers["seller name string here"] = /* put a seller here */;
//Search example:
std::unordered_map<Seller>::iterator it_result = sellers.find( "seller name string here" );
if( it_result != std::end( sellers ) )
std::cout << "Seller found!" << std::endl;
else
std::cout << "Seller not found :(" << std::endl;
}
How about using STD vector inside of SellerList instead of the array.
vector<Seller> x;
you can do x.push_back(Seller(...)) or x[0].SellerHasName() and x.size() will give you the number of sellers.
maybe something like this?
// Add a salesperson to the salespeople list IF the list is not full
// and if the list doesn't already contain the same name.
void SellerList::Add(string sellerName)
{
if(num < MAX_SELLERS)
salespeople[num++] = new Seller(sellerName);
}

Such a thing as C++ design pattern to avoid pointers?

I have a class hierarchy as shown in the example below, where a State contains a list of ZipCodes and a list of Citys, each of which contain pointers to the ZipCodes.
The goal is to be able to update the ZipCodes without needing to update Citys (or to create new instances of City).
The C++ code below meets this requirement, but it uses pointers, which I prefer to avoid because of this and that. How can I re-design this [naive] implementation so that it doesn't rely on pointers? Thanks for any help!
EDIT: Updated code below to use boost::shared_ptr instead of raw pointers. Note that State, City, and ZipCode are just example names, and they turned out to be poor choice names (I could've picked "A", "B", and "C") because the actual code allows the equivalent of City to share ZipCodes.
#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>
using namespace std;
/**
* Zone Improvement Plan (ZIP) code
*/
class ZipCode {
public:
ZipCode() : code_(0), plus4_(0) {}
ZipCode(int code, int plus4 = 0) : code_(code), plus4_(plus4) {}
virtual ~ZipCode() {};
int code() const { return code_; }
int plus4() const { return plus4_; }
void set_code(int code) { code_ = code; }
void set_plus4(int plus4) { plus4_ = plus4; }
private:
int code_;
int plus4_;
};
typedef boost::shared_ptr<ZipCode> ZipPtr;
/**
* City points to one or more zip codes
*/
class City {
public:
const vector<ZipPtr>& zip() const { return zip_; }
void add_zip_ptr(const ZipPtr x) { if (x != NULL) zip_.push_back(x); }
private:
// TODO: this vector should be a hash set
vector<ZipPtr> zip_;
};
/**
* State contains cities, each of which has pointers to
* zip codes within the state.
*/
class State {
public:
const vector<City>& city() const { return city_; }
const vector<ZipPtr>& zip() const { return zip_; }
const ZipPtr zip_of(int code) const {
for (size_t i = 0; i < zip_.size(); i++) {
if (zip_[i]->code() == code) {
return zip_[i];
}
}
return ZipPtr();
}
void add_city(const City& x) { city_.push_back(x); }
void add_zip(int code) { zip_.push_back(ZipPtr(new ZipCode(code))); }
private:
// TODO: these vectors should be hash sets
vector<City> city_;
vector<ZipPtr> zip_;
};
int main() {
State texas;
City dallas, houston;
// create state ZIPs
texas.add_zip(75380);
texas.add_zip(75381);
texas.add_zip(77219);
texas.add_zip(77220);
// point city ZIPs to the ones we just created
dallas.add_zip_ptr(texas.zip_of(75380));
dallas.add_zip_ptr(texas.zip_of(75381));
houston.add_zip_ptr(texas.zip_of(77219));
houston.add_zip_ptr(texas.zip_of(77220));
// print all ZIPs
cout << "ZIPs in Texas: " << endl;
const vector<ZipPtr>& zips = texas.zip();
for (size_t i = 0; i < zips.size(); i++) {
cout << " " << zips[i]->code() << endl;
}
cout << "ZIPs in Dallas, Texas: " << endl;
const vector<ZipPtr> zip_ptrs1 = dallas.zip();
for (size_t i = 0; i < zip_ptrs1.size(); i++) {
cout << " " << zip_ptrs1[i]->code() << endl;
}
cout << "ZIPs in Houston, Texas: " << endl;
const vector<ZipPtr> zip_ptrs2 = houston.zip();
for (size_t i = 0; i < zip_ptrs2.size(); i++) {
cout << " " << zip_ptrs2[i]->code() << endl;
}
// change a state ZIP...
cout << "Changing Houston's ZIP 77220..." << endl;
ZipPtr z = texas.zip_of(77220);
if (z != NULL) z->set_code(88888);
// ...and show the ZIPs of the affected city
cout << "ZIPs in Houston, Texas: " << endl;
const vector<ZipPtr> zip_ptrs3 = houston.zip();
for (size_t i = 0; i < zip_ptrs3.size(); i++) {
cout << " " << zip_ptrs3[i]->code() << endl;
}
return 0;
}
I see the situation as two 1:n relationships
State : City == 1 : n
City : Zipcode
== 1 : n
Based on that, I think that the State containing
vector<ZipCode> zip_;
is not sound.
I might do
class State {
vector< City > cities_in_state_;
};
class City {
vector< Zipcode > zips_in_city_;
};
This does not require pointers.
Unless you want to duplicate your ZipCode objects, you fall into this category of usage (described in your first link):
The Bar instance is actually managed
by some other part of your program,
whereas the Foo class just needs to be
able to access it.
It seems like a legit use.
However, you might want to consider the copy option (to permanently avoid problems if the vector has to reallocate its data) or make State aggregate ZipCodes from its Cities instead of distributing them ZipCodes.
The copy simply implies that you stop using pointers in City. Aggregating the ZipCodes means that instead of giving State a list of ZipCodes, you would give City the list of ZipCode instances, and when calling zip_of, you would iterate through the cities and iterate through their ZipCode collection.