Objects Array - C++ - c++

i am having a bit of trouble here. I dont know what i am doing wrong. My bike.cpp class is fine. But i think the problem is with bike_shed class, i am having problem with the "park" and "checklegal" methods. we are asked to do something like this: " The class BikeShed with a private array of 10 default constructed Bike objects. The class should have the following public methods:
A default constructor BikeShed() as supplied by the compiler.
A function bool park( const Bike& ) which adds a bike to an available
spot and returns true. If the BikeShed is full, the function returns
false.
A function Bike remove( const string&int ) that removes and returns
the first bike with an owner of the given name. If such a bike is not
found, the function returns a bike "None".
A function bool checkLegal() that will return true if all bikes
owned by other than "None" are legal. If a bike is found illegal
print a message printing the bike.
A function void print( ) that prints all the bikes with owners
other than "None"."
here is my code:
here is bike_shed.cpp file
#include <iostream>
#include "bike_shed.h"
#include "Bike.h"
using namespace std;
void bike_shed::print(){
cout<< "Bike: " << sizeof(Bike) <<endl;
}
bool bike_shed::checkLegal() {
Bike bike1;
if(bike1.getOwner() == "None"){
return false;
}
else{
return true;
}
}
//Bike bike_shed::remove( const string&, int ) {
//
//
//}
bool bike_shed::park( const Bike& ) {
if (sizeof(Bike) > 10) {
return false;
}
}
and here is the Bike.cpp file
#include "Bike.h"
#include <iostream>
using namespace std;
void Bike::setNLight(int _light) {
d_nLight = _light;
}
void Bike::setBell(bool _bell) {
d_bell = _bell;
}
void Bike::setOwner(string _owner) {
d_owner = _owner;
}
void Bike::setReflector(bool _reflector) {
d_reflector = _reflector;
}
int Bike::getNLight() {
return d_nLight;
}
string Bike::getOwner() {
return d_owner;
}
bool Bike:: hasReflector() {
if (d_reflector == true) {
return true;
}
else {
return false;
}
}
bool Bike:: hasBell(){
if(d_bell == true) {
return true;
}
else{
return false;
}
}
bool Bike::isLegal() {
if (d_nLight >= 1 && d_reflector && d_bell) {
return true;
}
else {
return false;
}
}
void Bike::print() {
cout << "Owner: " << d_owner << " Color: " << d_color.Red << " " << d_color.Green << " " << d_color.Blue
<< " " << " Lights: " << d_nLight << " Bell: " << d_bell << " Reflector: " <<d_reflector << endl;
}
Bike::Bike(string name, Color color){
d_owner = name;
d_color = color;
}
and here is the bike_shed.h file
#include "Bike.h"
class bike_shed {
public:
bike_shed();
bool park( const Bike& );
Bike remove( const string&, int );
bool checkLegal();
void print();
public:
Bike bike[10];};
i would really appreciate if someone can help me. Thank you :)

In the following block of code,
if (sizeof(Bike) > 10) {
return false;
}
I am guessing that you are trying to make sure that you don't allow parking of more than 10 bikes in the shed.
In order to do that, you need to have a member variable in park_shed to indicate the number of bikes parked in the shed. Then, you can use:
bool bike_shed::park( const Bike& bike)
{
if ( number_of_parked_bikes < 10 )
{
bikes[number_of_parked_bikes] = bike;
++number_of_parked_bikes;
return true;
}
else
{
retun false;
}
}
Make sure to initialize number_of_parked_bikes to zero in the constructor.
The checkLegal function would be something like:
// Make it a `const` member function since it does not
// change anything in bike_shed.
bool bike_shed::checkLegal() const
{
bool isLegal = true;
for ( int i = 0; i < number_of_parked_bikes; ++i )
{
if ( bikes[i].getOwner() == "None" )
{
// No need to check whether this bike is legar or not.
}
else if (!bikes[i].isLegal() )
{
isLegal = false;
cout << "Illegal bike found.\n";
bikes[i].print();
}
}
return isLegal;
}

In method checkLegal() you may want to check whether a given Bike is valid or not before insertion, so you can write something like :
bool bike_shed::checkLegal(const Bike &bike1) {
if(bike1.getOwner() == "None"){ // or maybe bike1.isLegal()
return false;
}
else{
return true;
}
}
Also if you want to print all bikes in bike_shed you might want to write something like :
void bike_shed::print(){
for (int iBike = 0; iBike < nbBikes < iBike++)
bike[iBike].print();
}

Related

Can't call a function in a class returning a char

There is an error saying "expression preceding parentheses of apparent call must have (pointer-to-) function type" when I'm trying to call st.top()
string infixToPostfix(string hasil)
{
Stack st;
string postfix = "";
for (int i = 0; i < hasil.length(); i++)
{
if (hasil[i] == ' ')
{
continue;
}
else if (isOperator(hasil[i]))
{
while (st.isEmpty() && hasHigherPrecedence(st.top(), hasil[i])) // the error is here
{
postfix = postfix + st.top(); // and here
}
}
}
}
class Stack {
public:
int top = -1;
char array[MAX];
bool isEmpty()
{
if (top == -1)
{
return true;
}
else
{
return false;
}
}
bool isFull()
{
if (top == (MAX-1))
{
return true;
}
else
{
return false;
}
}
void push(char masuk)
{
if (isFull())
{
cout << "Expresi yang anda masukkan telah melebihi stack" << endl;
}
else
{
top++;
array[top] = masuk;
}
}
void pop()
{
if (isEmpty())
{
cout << "Stack sudah kosong!" << endl;
}
else
{
top--;
}
}
char top()
{
if (isEmpty())
{
cout << "Stack kosong" << endl;
}
else
{
return array[top];
}
}
};
You have both a public member variable and a public function called top. You should rename one of them.
You should also seriously consider making the variable (and, indeed, all variables) private since, otherwise, forces outside your class are free to fiddle with its internals in a way that you won't enjoy.
The whole point of encapsulation is hiding this sort of stuff from the outside world so that your class has a limited number of things it presents. For example, with a public variable, I could just do:
st.m_top = -2; // Assumes you've renamed it to distinguish from top().
and sit back and enjoy the fireworks :-)

Shared_ptr is null on re-iteration in std::Vector

I have the below program of an execution class which populates a map shown below
map<string,map<string,vector<StructAbsTypeObject>>>
Here I am making shared objects and assigning them which are valid during first check, but on second check shared_ptr returns null. I need to know the reason why. The code seems fine but don't know where is it going wrong.
//Code begins
#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <memory>
using namespace std;
class Test {
public:
Test(int i):t(i) {
}
private:
int t;
};
class ConcTypeObject {
public:
ConcTypeObject() {
}
ConcTypeObject(const ConcTypeObject& other) {
m_ptr_Test = other.m_ptr_Test;
}
ConcTypeObject& operator=(const ConcTypeObject& other) {
m_ptr_Test = other.m_ptr_Test;
}
void setTest(shared_ptr<Test> ptr) {
cout << "setTest" << endl;
m_ptr_Test = ptr;
}
shared_ptr<Test> getTest() {
return m_ptr_Test;
}
bool isValid() {
if(m_ptr_Test) {
return true;
} else {
return false;
}
}
private:
shared_ptr<Test> m_ptr_Test;
};
class AbsTypeObject {
public:
explicit AbsTypeObject(const string str) {
m_str = str;
}
AbsTypeObject(const AbsTypeObject& other) {
m_str = other.m_str;
m_ptr_ConcTypeObject = other.m_ptr_ConcTypeObject;
}
AbsTypeObject& operator=(const AbsTypeObject& other) {
m_str = other.m_str;
m_ptr_ConcTypeObject = other.m_ptr_ConcTypeObject;
}
bool operator==(const AbsTypeObject& other) {
if(m_str == other.m_str)
return true;
else
return false;
}
void setConcTypeObject(shared_ptr<ConcTypeObject> ptr) {
m_ptr_ConcTypeObject = ptr;
}
shared_ptr<ConcTypeObject> getConcTypeObject() {
return m_ptr_ConcTypeObject;
}
bool isValid() {
if(m_ptr_ConcTypeObject) {
cout << "AbsTypeObject 1 " << endl;
return m_ptr_ConcTypeObject->isValid();
} else {
cout << "AbsTypeObject 2 " << endl;
return false;
}
}
private:
string m_str;
shared_ptr<ConcTypeObject> m_ptr_ConcTypeObject;
};
class StructAbsTypeObject {
public:
StructAbsTypeObject(const string str):m_AbsTypeObject(str) {
}
void SetAbsTypeObject(AbsTypeObject& id) {
m_AbsTypeObject = id;
}
AbsTypeObject& GetAbsTypeObject() {
return m_AbsTypeObject;
}
private:
AbsTypeObject m_AbsTypeObject;
};
class Executor {
public:
static Executor m_Executor;
static Executor& get() {
return m_Executor;
}
Executor() {
StructAbsTypeObject sid(std::string("ABCD"));
vector<StructAbsTypeObject> a_vecstid;
a_vecstid.push_back(sid);
m_executormap["ExecutorInterface"]["ExecutorName"] = a_vecstid;
}
void check() {
for(auto outermap : m_executormap) {
for(auto innermap : outermap.second) {
for(auto vec_element: innermap.second) {
if(vec_element.GetAbsTypeObject().isValid()) {
cout << "PTR VALID" << endl;
} else {
cout << "PTR NOT Valid" << endl;
}
}
}
}
}
void fillAbsTypeObject(AbsTypeObject &id) {
shared_ptr<Test> ptr_test = make_shared<Test>(20);
shared_ptr<ConcTypeObject> ptr_ConcTypeObject = make_shared<ConcTypeObject>();
id.setConcTypeObject(ptr_ConcTypeObject);
id.getConcTypeObject()->setTest(ptr_test);
}
void Init(AbsTypeObject id) {
for(auto outermap : m_executormap) {
for(auto innermap : outermap.second) {
for(auto vec_element: innermap.second) {
if(vec_element.GetAbsTypeObject() == id) {
cout << "Id Equal" << endl;
fillAbsTypeObject(id);
vec_element.SetAbsTypeObject(id);
if(vec_element.GetAbsTypeObject().isValid()) {
cout << "PTR VALID" << endl;
} else {
cout << "PTR NOT Valid" << endl;
}
}
}
}
check();
}
}
private:
using executormap = map<string,map<string,vector<StructAbsTypeObject>>>;
executormap m_executormap;
};
Executor Executor::m_Executor;
int main()
{
AbsTypeObject id(std::string("ABCD"));
Executor::get().Init(id);
}
//Code Ends
The above code is completely compilable and Runnable. Currently I am getting the following output
//Output Begins
Id Equal
setTest
AbsTypeObject 1
PTR VALID
AbsTypeObject 2
PTR NOT Valid
//Output Ends
The PTR NOT VALID is output when check function is executed. Expecting output is
PTR VALID in both cases.
Please let me know what is going wrong in the above code. I did try few things but did not work. If it does not work, what is the reason and what is the correct way to make it work.
Thanks in advance.
In your for loops:
for(auto outermap : m_executormap) {
for(auto innermap : outermap.second) {
for(auto vec_element: innermap.second) {
You are using auto which defaults to a non-reference type so you are taking a copy of each element in the map/vector. Your changes are being applied to these temporary copies so are lost.
Simply change these to references to update the original lists:
for(auto& outermap : m_executormap) {
for(auto& innermap : outermap.second) {
for(auto& vec_element: innermap.second) {

How to test the given ADT implementation with templates such as <int, int> and <string, int>?

I am working on a problem that requires the implementation of two ADT's. After Implementing, I need to test my bag implementations with the following template combinations:
<int, string>-- all functions
<string, int> -- insert and find functions only
My testing so far has been entering integers to test the different functions. I do not understand what it means to test the implementations with the templates.
Here is my bagADT implementation:
#include <stdlib.h>
#include "bagADT.h"
template <typename E>
class ABag : public Bag<E> {
private:
int maxSize;
int listSize;
E* listArray;
public:
ABag(int size = defaultSize) { // Constructor
maxSize = size;
listSize = 0;
listArray = new E[maxSize];
}
~ABag() { delete[] listArray; } // Destructor
bool addItem(const E& item) {
if (listSize >= maxSize) {
return false;
}
listArray[listSize] = item;
std::cout << "Add Item: Added " << item << " in spot " << listSize << std::endl;
listSize++;
return true;
}
bool remove(E& item) {
for (int i = 0; i < listSize; i++) {
if (listArray[i] == item) {
std::cout << "Remove: Removed " << item << " from position ";
item = i;
std::cout<< item << " and adjusted the location of all other elements." << std::endl;
for (i= item; i < listSize; i++) {
listArray[i] = listArray[i + 1];
}
listSize--;
return true;
}
}
return false;
}
bool removeTop(E& returnValue) {
if (listSize == 0) {
return false;
}
else {
returnValue = listArray[listSize - 1];
std::cout << "Remove Top: Removed " << returnValue << " from the top of the stack." << std::endl;
for (int i = listSize; i < maxSize; i++) {
listArray[i] = listArray[i + 1];
}
listSize--;
return true;
}
}
bool find(E& returnValue) const {
for (int i = 0; i < (listSize - 1); i++) {
if (listArray[i] == returnValue) {
returnValue = i;
return true;
}
}
return false;
}
bool inspectTop(E& item) const {
if (listSize == 0) {
return false;
}
else {
item = listArray[listSize - 1];
std::cout << "Inspect Top: The value on top is currently " << item << "." << std::endl;
return true;
}
}
void emptyBag() {
delete[] listArray;
listSize = 0;
listArray = new E[maxSize];
std::cout << "Empty Bag: Emptied the bag." << std::endl;
}
bool operator+=(const E& addend) {
if (listSize < maxSize) {
return true;
}
return false;
}
int size() const {
std::cout << "Size: Number of elements in listArray: " << listSize << std::endl;
return (listSize - 1);
}
int bagCapacity() const {
std::cout << "Bag Capacity: The capacity of this bag is " << maxSize << std::endl;
return maxSize;
}
};
Here is another file provided by my professor called kvpairs:
#ifndef KVPAIR_H
#define KVPAIR_H
// Container for a key-value pair
// Key object must be an object for which the == operator is defined.
// For example, int and string will work since they both have == defined,
// but Int will not work since it does not have == defined.
template <typename Key, typename E>
class KVpair {
private:
Key k;
E e;
public:
// Constructors
KVpair() {}
KVpair(Key kval, E eval)
{
k = kval; e = eval;
}
KVpair(const KVpair& o) // Copy constructor
{
k = o.k; e = o.e;
}
void operator =(const KVpair& o) // Assignment operator
{
k = o.k; e = o.e;
}
bool operator==(const KVpair& o) const {
if (o.k == k) {
return true;
}
return false;
}
//The following overload is provided by Adam Morrone, Spring 2016 class.
//Thanks Adam :)
friend ostream& operator<<(ostream& os, const KVpair& o) // output print operator
{
os << "Key: " << o.k << " Value: " << o.e;
return os;
}
// Data member access functions
Key key() { return k; }
void setKey(Key ink) { k = ink; }
E value() { return e; }
};
#endif
I am expected to show the test outputs using the above templates, but I have no idea how to do this. Also, ignore the += overload. It is incorrect and I know. I am supposed to overload it to directly add a new int to the array.
I think I understand now. I could be wrong, but this is my guess.
Your bag is singly templated, but it will be holding KVpair. They said they will use KVpair with <int, string> and <string, int>.
When they talk about testing it, that means they will be instantiating it as follows:
int main() {
ABag<KVPair<int, string>> bag;
bag.addItem(KVpair(1, "hi"));
//...
}
This is what I am pretty sure they mean by "testing it with templates".
As a minor edit, I don't know what C++ version you are using but if it's very archaic, you might need to write template instantiation like ABag<KVPair<int, string> > instead of putting them together. I remember vaguely this being an issue a long time ago.

Cant get arrays to keep value in class

When I use the object function set_and_make_variable I send it a name and value which both work correctly. However then when I go to use show current_variables it acts like I never set the values for both integers, and integers_names. I thought you could modify the variables arrays from the functions associated with the class without references or pointers.
Am I not correct?
void reset_name(string *variable_names)
{
for (int i = 0; i < 100; i++)
{
variable_names[i] = "";
}
}
void reset_int_value(int *variable_value)
{
for (int i = 0; i < 100; i++)
{
variable_value[i] = 0;
}
}
int find_next(string variable_names[100])
{
for (int i = 0; i < 100; i++)
{
if (variable_names[i] == "")
{
return i;
}
}
}
//*****************************************************************
class variables_integers
{
public:
string integer_names[100];
int integers[100];
variables_integers(void);
void set_and_make_variable(string, int);
void show_current_variables(void);
};
variables_integers::variables_integers(void)
{
reset_int_value(integers);
reset_name(integer_names);
}
void variables_integers::show_current_variables(void)
{
cout << "INTEGERS:" << endl;
for (int i = 0; i < (find_next(integer_names)); i++)
{
cout << integer_names[i] << " = " << integers[i] << endl;
}
}
void variables_integers::set_and_make_variable(string name, int value)
{
cout << name << " " << value << endl;
cout << find_next(integer_names) << endl;
integers[find_next(integer_names)] = value;
integer_names[find_next(integer_names)] = name;
}
//*** added code ******
bool operations_and_declerations(string parsed_input[3000], variables variable)
{
if (parsed_input[0] == "int")
{
if (parsed_input[2] == "=")
{
variable.integers.set_and_make_variable(parsed_input[1], atoi(parsed_input[3].c_str()));
}
return true;
}
else if (parsed_input[0] == "string")
{
return true;
}
//else if (parsed_input[0] ==)
else
{
return false;
}
}
In operations_and_declerations(), you sent your variables parameter by value. Hence, the function created a local copy, and only modified that local copy.
You can fix the problem by sending it the parameter by reference. Just modify the function name to:
bool operations_and_declerations(string parsed_input[3000], variables & variable)

Convert from pointer to an object c++

I have got a problem with understanding the following code where I am trying to convert from the pointer to an object class Passenger* passenger to class Passenger passenger. I am not sure how I can modify my code to do perform the same functionality without the pointers. I am particularly confused with setting and comparing to NULL. Do I need to keep those if statements if I am no longer using the pointers? Any advises or suggestions would be appreciated.
class Seat
{
private:
class Passenger* passenger;
public:
Seat()
{
passenger = NULL;
}
~Seat()
{
if (passenger)
{
delete passenger;
passenger = NULL;
}
}
bool insertSeat(class Passenger* p)
{
bool bsuccess = TRUE;
if ( p != NULL )
{
if (passenger == NULL)
passenger = p;
else
bsuccess = FALSE;
}
else
passenger = NULL;
return bsuccess;
}
bool outputSeat(int row,int seat)
{
if (passenger)
cout << (passenger->toString()) << endl;
else
cout << "Empty " << row << seat+'A' << endl;
return passenger != NULL;
}
};
The simplest way is :
class Seat
{
private:
Passenger passenger;
public:
Seat()
{ }
void insertSeat( const Passenger& p ) // pass by const reference
{
passenger = p;
}
bool outputSeat( int row, int seat )
{
cout << passenger.toString() << endl;
}
};
You can always implement checking; eg : you don't want an invalid or default constructed passenger when passing it to
insertSeat() function :
bool insertSeat( const Passenger& p ) // pass by const reference
{
if( /* p.empty() or p.invalid() or whatever*/ ) return false; // implement empty() method
passenger = p;
return true
}