I do not understand how to implement the following code to allow the function to write into the existing array.
void Project::addStaff(const Staff&)
{
//add employees into staff array
}
having (const Staff&) as parameters is new to me as it does not create an object anyways. I can not change it because it is to be used as is to implement the program correctly. the Staff constructor is as follows
Staff::Staff (std::string lname, std::string fname)
: theLname(lname), theFname(fname)
{}
Is there a way to write the variable for staff so I can access the needed values to place into the array? Any help would be greatly appreciated!
Your Project class may have a std::vector data member, and you can use vector.push_back() method to add new Staff instances in the array:
// Inside Project class:
std::vector<Staff> m_staffPersons;
void Project::addStaff(const Staff& newStaff)
{
// Add employees into staff array
m_staffPersons.push_back(newStaff);
}
I would define std::vector<Staff> representing list of employees as a member of this Project class:
class Project
{
public:
void addStaff(const Staff&);
vector<Staff> employees;
}
Then your addStaff method could look like this:
void Project::addStaff(const Staff& newEmployee)
{
employees.push_back(newEmployee);
}
But I would definitely rename class Staff since it doesn't say much about itself. Employee would be much better name for this class.
Related
I'm trying to declare a vector containing user objects in the header file, but I'm unsure of how to use the setter and getter functions to push values objects back to the vector or call them again.
class userbase
{
public:
userbase();
virtual ~userbase();
//FUNCTION DECLARATIONS
void record_User(user);
void setUserVector(vector<user> const &newUser) {
//userbase_V = newUser;
userbase_V.push_back(newUser);
}
vector<user> const &getUservector() const {
return userbase_V;
}
protected:
private:
vector <user> userbase_V;
};
Getters/setters are quite often misunderstood. The aim of using such functions is encapsulation which means restricting access to your data or exposing certain functions.
The reason why we don't make private members public in the first place is because there are some operations that we don't want users of our class to perform.
Consider the following class:
class userbase
{
public:
vector<user> users;
};
Let's say the goal of the userbase class is to manage a loyal, unwavering list of followers of an application. And since users is a public member, we can do whatever we want with it:
class company
{
public:
void massacre()
{
m_userbase.users.clear(); // Aaaaahhh!!!
}
private:
userbase m_userbase;
};
What? Where did all our loyal, unwavering followers go? We can't just remove our users!
The company class has access to all of std::vector's functionality on m_userbase.users. But really, from userbase's point of view, we don't want the outside to access particular functions (in this case, clear() or erase()). We want to restrict what operations can be performed (modifiers) and what attributes can retrieved (accessors). That is, we want to encapsulate the users vector.
Making userbase a private member is the first step:
class userbase
{
private:
vector<user> users;
};
Now let's add some naive "encapsulation" to see if it solves our problem. (This is where a lot of misunderstanding stems from.)
Here's our new class:
class userbase
{
public:
void setUsers(vector<user> const& newUsers) {
users = newUsers;
}
vector<user> const& getUsers() const {
return users;
}
private:
vector<user> users;
}
Can the company still clear the users vector directly? Yes.
class company
{
public:
void massacre()
{
auto users = m_userbase.getUsers();
users.clear();
m_userbase.setUsers(users); // Aaaaahhh!!!
// or simply create a new vector with no data
m_userbase.setUsers(std::vector<user>{}); // Aaaaahhh!!!
}
private:
userbase m_userbase;
};
So simply providing getters/setters doesn't solve the issue.
The common approach is to instead approach it the other way around. Instead of asking "What don't I want the outside to do?", ask "What do I want to allow the outside to do?". This way, you can figure what sort of functionality to expose. This is part of designing a good API.
Maybe our API wants to be able to: add a user, get a user's name, and count the number of users. Then we would design a class like this:
class userbase
{
public:
/// modifiers:
// Add a user to the userbase.
void addUser(User const& user);
/// accessors:
// Returns the user's name given its index.
string getUserName(size_t index) const;
// Returns the number of users belonging to this userbase.
size_t numberOfUsers() const;
private:
vector<user> m_users;
};
The takeaway is: it's up to you to decide what "the outside" can or can't do with its members. You'll need to spend more time thinking and less time writing code, but this is normal.
Further reading:
Why use getter and setters? (A good read even though it's tagged with Java.)
I have an assignment to make Information system about resorts in a country, be able to read/write data for the resorts from/to file and modifying it.
class CTŠ¾urist{
string m_StrName;
string m_StrCountry;
int m_iAge;
public:
//constructors, mutators, accessors overloading operator <<,>>
};
I don't have problem writing this class. And here I have class which contains as member variable vector of the first class's objects
class CHotel
{
string m_strHotelName;
int m_iNumberOfBets;
double m_dAveragePrice; //average price per bet in the hotel
vector <CTourist> m_vecTourists; //vector of tourists rested in the hotel
public:
.....
};
And one more class Resort containing as member variable vector of the second class's objects
class CResort
{
string m_ResortName;
unsigned m_Height;
vector<CHotel*> m_Hotels;
public:
.....
};
So here is the problem. I'm not sure how to write the accessor,mutator and constructors for that vector variable so I can use them property. Thank you for checking and if someone could help me figure out these functions I'll be really grateful!
if i understand correctly you want to know the best way to get your hotels from cResort.
i would recommend
cHotel* GetHotelByName(std::string& a_sName)
{
for(int i = 0; i < m_Hotels.size(); ++i)
{
if(m_Hotel[i].GetName() == a_sName)
return m_Hotel[i]
}
return nullptr; // if non found return return null
}
and add a GetName function to your hotel class which returns a string of its name.
this also allows you to SetName etc.
1) Accessor, mutator: There are plenty of options.
You can create another class like CTouristList (and CHotelList respectively), that wraps the vector, have it referenced from the CHotel class (accessor methods like CTouristList& CHotel::GetTouristList() and const CTouristList& CHotel::GetTouristList() const) and implement methods like CTouristList::Add, CTouristList::Remove, CTouristList::Get, etc.
Or you can add methods like CHotel::AddTourist() directly on the CHotel class.
2) Constructor. Nothing needed in constructor. But for vector<CHotel*> you may need destructor in CResort to explicitly free the CHotel instances. Though not sure why you want to use pointers to CHotel.
You can put the accessor and mutator functions in CTourist just like you would if they were not being stored in a Vector.
To utilize them once they are in CHotel you could add a function in CHotel that returns a pointer to a CTourist.
// Access a CTourist
Hotel.getTourist(1)->setName("Tourist name");
Adding a method that returns the number of tourist that visited a hotel would make it easier to loop through them.
for(int i = o; i < Hotel.touristCount(); ++i)
{
// Do something useful
std:: cout << "Hello " << Hotel.getTourist(i)->getName();
}
In that case your CHotel::touristCount() would be a wrapper around the vector<>.size();
If you do not want code outside of CHotel to have direct access to a CTourist object then create wrapper functions in CHotel that do what you would want to do externally.
i.e.
std::cout << Hotel.getTouristName(1);
instead of
std::cout << Hotel.getTourist(1)->getName();
I need to build a constructor for a Vector of pointers to classes...
My class is :
class Song {
string song_name;
string auther_name;
int popularity;
SongStructure song_format;
int song_length;
int lengths[size];
bool first_condition_true();
bool second_condition_true(int index);
}
};
My vector is :
vector<Song*> play_list;
With the new standard C++11 / 0x initializer list has been introduced:
I assume you wanted to create a SongBook class containing a vector of Song-Pointers and then additional Infos.
They can be used like this:
Class file:
class SongBook {
vector<Song*> songlist;
string name;
// Constructor
SongBook(std::initializer_list<Song*> songs) : songlist(songs) {}
}
and then call like this from your main for example
SongBook book({new Song(...), new Song(...), new Song(...)});
Your vector have a working constructor that you can use. (It create place for the pointers). What you are asking for is probably a way to make the pointers point to some valid Song. You will need to do that in some loop (STL "loop" probably). But you probably dont need that, becouse your Song is legaly copyable!?. You can use vector<Song>
I'm doing a restaurant management program. Right now I'm trying to output private vector data and am getting stuck.
So I have a Menu.h
private:
vector<Category> categories;
vector<Menu_Item> menu_items;
vector<Recipe> recipes;
vector<Ingredient> ingredients;
vector<Order> orders;
vector<Order_Item> order_items;
And Menu.cpp
Menu.read()
Menu.show()
The read function reads from a file like this
1010 Appetizers
1901 Entrees
1576 Desserts
1320 Drinks
And stores those values into the appropriate vector, for example this one would be vector categories.
I also have a .h file for all the different types of things like, Menu_Item.h, Recipe.h, etc. And I store values into the vector like such:
menu_items.push_back(Menu_Item(meniID, catID, rID....
However in Menu_Item.h the values are
private:
int menu_item_id;
int cat_id;
int recipe_id;
string menu_item_name;
double price;
The show() function queries the user what he/she wants to see. Let's say the user wants to see a specific menu item like Onion rings. What I can't do is
if(menu_items[0].menu_item_name == "Onion Rings")
because it says that menu_item_name value is private within Menu_Item.h. How can I access the private data?
You have to make menu_items public or make a public getter function like the following.
public:
vector<Menu_Item> get_menu_items(){ return menu_items;}
Then say if you had a Menu object of this type called Menu you can do this:
if(Menu.get_menu_items()[0].menu_item_name == "Onion Rings")
The other possible option is that you make a friend class if another specific class needs access, though usually this won't be the best design decision.
In response to the comment you could do this:
for(size_t n=0, n<menu_items.size()-1, ++n){
if(Menu.get_menu_items()[n].menu_item_name == "Onion rings")
cout << "something";
}
Two options:
Declare your fields in Menu_item.h as public, not private.
Keep your fields as private, but create public getters (and setters) to access the fields.
So I am trying to define a class and I am using another array of a different class to define it.
//header file for Name.h
class Name {
string last;
string first;
};
//header file for Depositor.h
class Depositor {
Name name;
string ssn;};
//header file for Account.h
class Account {
Depositor depositor;
int acctnum;
string type;
double balance;
};
//header file for Bank.h
#include "Account.h"
class Bank {
Account account[]; //is this possible?
int active_accts;
};
When I am writing the cpp file I am running into a lot of problems!
//example of mutator
void Bank::setLastname(string lastname)
{
account.setLastname (lastname);
}
I didn't include the mutators and acessors that I wrote into the header file, but they are there and are public -- it won't compile.
Can you help? Is it even valid to use an array of a class in Bank.h?
Is it even valid to use an array of a class in Bank.h?
Yes, but it has to have a fixed dimension, e.g.,
Account account[3];
A type always has a fixed size in C++, and since an array member variable forms part of the class's size, you need to specify how many elements are in the array.
If you don't know how many elements you are going to need, you can use a sequence container:
std::vector<Account> account;
Account is not a nested class of Bank. Bank has a member data instance of type Account array.
You can have a primitive array member in a class, but you must specify the size of the array in the class definition: Account account[42];. The reason is that when you #include the class definition in another compilation unit, and then instantiate an instance of the class, the compiler needs to know what the size of that instance is.
It would be a wise idea to use std::vector<Account> rather than a primitive array. std::vector doesn't require committing to a particular size at construction; it grows dynamically. How come a std::vector doesn't require a size in the class definition, while a primitive array does? A std::vector holds as member a pointer to the elements on the heap. So the compiler does know the size of a std::vector; it uses the size of the pointer rather than the count of the elements.
By declaring the value of the array in the header file and by adding a variable in the .cpp file you can solve all the problems and leave it as an array.
//header file
class Bank {
Account account[100];
int active_accts;
public:
//mutator
void setLastname (string,int);
};
//the implementation file
void Bank::setLastname (string last, int index)
{
account[index].setLastname(last);
}
this will solve all your problems
account is an array of Accounts, which means you would need to do something like account[0].setLastname(lastname);
Instead of arrays, consider using vectors.
#include <vector>
// ...
class Bank {
std::vector<Account> accounts;
int active_accts;
};
you can't call setLastname(lastname) on the whole array. You need to call it on a specific instance of the Account class inside the array, like this: account[0].setLastname(lastname);
On another note, you really should be storing an array of pointers to Account objects.