Accessing private member function - c++

Good day! In the school project I'm working, bool isFull() and bool isEmpty() should be in private. However in the default code that is given to us, isEmpty is called in the main program. Is there a way for me to access isEmpty
//data.h
#pragma once
class IntQueue
{
private:
int *queueArray;
int queueSize;
int front;
int rear;
int numItems;
bool isFull();
bool isEmpty();
public:
IntQueue(int);
~IntQueue();
void enqueue(int);
void dequeue(int &);
void clear();
};
//main.cpp
while (!iQueue.isEmpty())
{
int value;
try{
iQueue.dequeue(value);
}
catch(const std::invalid_argument) {
cout << "Exception occurred: Queue Underflow!" << endl;
}
cout << value << endl;
}
}

Related

C++: Why Position constructor are called when the argument type does not match?

This will be a bit lengthy but anyhow i tried my best to simplify it using code.
I am building a binary tree but noticed something peculiar.
linked_binary_tree.h
#ifndef LINKED_BINARY_TREE_H
#define LINKED_BINARY_TREE_H
#include <iostream>
#include <list>
using namespace std;
typedef int Elem;
class LinkedBinaryTree {
protected:
struct Node {
Elem ele;
Node *par;
Node *left;
Node *right;
Node(): ele(), par(NULL), left(NULL), right(NULL) {}
};
public:
class Position {
friend LinkedBinaryTree;
private:
Node *v;
public:
Position(Node *_v=NULL): v(_v) { cout << "Position constr" << endl;}
Elem &operator*() const {
return v->ele;
}
Position left() const {
return Position (v->left);
}
Position right() const {
return Position (v->right);
}
Position parent() const {
return Position(v->par);
}
bool isRoot() const {
return v->par==NULL;
}
bool isExternal() const {
return v->left==NULL && v->right==NULL;
}
};
typedef list<Position> PositionList;
LinkedBinaryTree();
int size() const;
bool empty() const;
Position root() const;
PositionList positions(int trv) const;
void addRoot();
void expandExternal(const Position &p);
Position removeAboveExternal(const Position &p);
protected:
void preorder(Node *v, PositionList &pl) const;
void postorder(Node *v, PositionList &pl) const;
void inorder(Node *v, PositionList &pl) const;
private:
Node * _root;
int n;
};
#endif
linked_binary_tree.cc
#include <iostream>
#include <list>
#include "linked_binary_tree.h"
using namespace std;
LinkedBinaryTree::LinkedBinaryTree(): _root(NULL), n(0) {}
int LinkedBinaryTree::size() const {
return n;
}
bool LinkedBinaryTree::empty() const {
return size()==0;
}
LinkedBinaryTree::Position LinkedBinaryTree::root() const {
cout << "LinkedBinaryTree::root()" << endl;
return Position(_root);
}
void LinkedBinaryTree::addRoot() {
_root=new Node;
n=1;
_root->ele=n;
}
void LinkedBinaryTree::expandExternal(const Position &p) {
Node *v = p.v;
v->left=new Node;
v->left->par=v;
v->left->ele=++n;
v->right=new Node;
v->right->par=v;
v->right->ele=++n;
}
LinkedBinaryTree::PositionList LinkedBinaryTree::positions(int trv) const {
PositionList pl;
if (trv==1)
preorder(_root,pl);
else if (trv==2)
inorder(_root,pl);
else postorder(_root,pl);
return PositionList(pl);
}
void LinkedBinaryTree::preorder(Node *v, PositionList &pl) const {
pl.push_back(Position(v));
if (v->left!=NULL)
preorder(v->left,pl);
if (v->right!=NULL)
preorder(v->right,pl);
}
void LinkedBinaryTree::postorder(Node *v, PositionList &pl) const {
if (v->left!=NULL)
preorder(v->left,pl);
if (v->right!=NULL)
preorder(v->right,pl);
pl.push_back(Position(v));
}
void LinkedBinaryTree::inorder(Node *v, PositionList &pl) const {
if (v->left!=NULL)
preorder(v->left,pl);
pl.push_back(Position(v));
if (v->right!=NULL)
preorder(v->right,pl);
}
linked_binary_tree_main.cc
#include <iostream>
#include "linked_binary_tree.h"
using namespace std;
int main() {
LinkedBinaryTree lbt;
lbt.addRoot();
cout << "post addRoot()" << endl;
LinkedBinaryTree::Position pr = LinkedBinaryTree::Position(lbt.root()); // --> STATEMENT 1
cout << "post lbt.root()" << endl;
//LinkedBinaryTree::Position pr = lbt.root(); // --> STATEMENT 2
lbt.expandExternal(pr);
cout << "LinkedBinaryTree.size() :- " << lbt.size() << endl;
// 1-preorder 2-inorder 3-postorder
auto iter=lbt.positions(3);
auto cbeg=iter.cbegin();
auto cend=iter.cend();
for (; cbeg!=cend; cbeg++) {
cout << cbeg->operator*() << " ";
}
cout << endl;
return 0;
}
Results executing linked_binary_tree_main
post addRoot()
LinkedBinaryTree::root() --> STATEMENT 3
Position constr --> STATEMENT 4
post lbt.root()
LinkedBinaryTree.size() :- 3
Position constr
Position constr
Position constr
2 3 1
Note:
Statement 1
LinkedBinaryTree::Position pr = LinkedBinaryTree::Position(lbt.root()); // --> STATEMENT 1
a. The lbt.root() actually returned LinkedBinaryTree::Position instance.
b. There is no LinkedBinaryTree::Position constructor which takes in a Position instance. Instead it has the following:
Position(Node *_v=NULL): v(_v) { cout << "Position constr" << endl;}
which is it takes a pointer to a Node argument. Yet STATEMENT 1 works showing that LinkedBinaryTree::Position(Node *v) constructor is called.
c. If you comment out STATEMENT 1 and use STATEMENT 2 that of course would work as well.
So why does STATEMENT 1 works?
Appreciate any insight.
Thanks.
The constructor you're seeing is not the one you think it is.
The constructor in STATEMENT 1 is the (compiler-generated) copy-constructor.
The constructor printing the output Position constr happens in the LinkedBinaryTree::root function:
return Position(_root);
This was much easier to see once I created a more minimal example (together with some extra output).

delete function of queue

I'm facing a problem with my queue delete function. Please have a look at the following code.
class queueType // public queueADT<Type>
{
public:
const queueType<Type>& operator=(const queueType<Type>&);
bool isEmptyQueue() const;
bool isFullQueue() const;
void initializeQueue(int);
void minusIo(int);
Type & front();
Type & back();
void addQueue(const Type& queueElement);
void addQueueFront(const Type& newElement);
void deleteQueue();
queueType(int queueSize = 100);
queueType(const queueType<Type>& otherQueue);
~queueType();
bool operator== (const queueType<Type>&);
bool operator!= (const queueType<Type>&);
void deleteBackOfQueue();
void printQueue();
void sort();
bool notin(Type f);
void shortest(int);
Type *list;
int count;
Type & any(int);
void deleteany();
private:
int maxQueueSize;
int queueFront;
int queueRear;
bool isEqual(const queueType<Type>&);
};
The below is given my delete queue and print functions.
template<class Type>
void queueType<Type>::deleteQueue()
{
if (!isEmptyQueue())
{
queueFront = ++queueFront % maxQueueSize;
count--;
}
else
cout << "Cannot remove from an empty queue" << endl;
}
Following is the print function.
template
void queueType<Type>::printQueue()
{
for (int i = 0; i<count; i++)
{
cout << list[i];
}
}
I used it in my main function as following.
void main()
{
queueType<int> RQ;
RQ.addQueue(2);
RQ.addQueue(8);
RQ.addQueue(7);
RQ.addQueue(2);
RQ.addQueue(4);
RQ.printQueue();
cout << endl;
RQ.deleteQueue();
RQ.printQueue();
getchar();
}
It is showing the following result.
28724
2872
I don't understand why it is deleting from the end and not from the front. To me code seems fine. Please have a look and let me know.
Since your delete function does not modify "list" your print should not start from zero but from queueFront. An easy way to achieve this is by replacing:
cout << list[i];
with:
cout << list[i+queueFront];
In your printing function.
But you should look into modifying list in some way, while still keeping a pointer to the memory you have to free.

Dynamic object array increase

I'm building a domino game and trying to make a function that adds a Stone to a pile.
This is the Stone class:
class Stone
{
public:
Stone(){ left = 0; right = 0; };
Stone(int x, int y){ left = x; right = y; };
void turnStone();
bool comStones(const Stone&);
void printOpen();
void printClosed();
friend class Pile;
friend class Game;
private:
int left, right;
};
And this is the Pile class:
class Pile
{
public:
Pile(){};
Stone indexfun(int);
void printOpen();
void printClosed();
void fillPile();
void randPile();
void addStone(Stone&);
void remStone(Stone&);
friend class Player;
friend class Game;
private:
Stone* list;
int size=0;
};
Now the function I built for adding a stone to the pile is:
void Pile::addStone(Stone& newStone) {
Stone* newList = new Stone[size + 1];
int i;
for (i = 0; i < size; i++)
{
newList[i] = list[i];
}
newList[i] = newStone;
delete[] list;
list = newList;
size++;
}
When I try and build the newlist array it throws me out of the program. can't find the reason. Help anyone?
the previous functions and more classes in the project:
class Game
{
public:
Game(char*);
void run();
private:
Player human, computer;
Pile box, table;
int start, finish;
void playerMove(int);
void checkPile(int);
bool checkMove(int,int);
bool whosFirst();
bool checkGame();
void printTable();
};
class Player
{
public:
Player(){};
void addStone(Stone&);
void remStone(Stone&);
void printPile();
Stone* searchStone();
friend class Game;
private:
char* name;
Pile pie;
};
void Game::run() {
cout << "starting the game" << endl;
box.fillPile();
box.size = 28;
box.randPile();
for (int i = 0; i < 7; i++)
{
human.addStone(box.list[i]);
box.remStone(box.list[i]);
computer.addStone(box.list[i]);
box.remStone(box.list[i]);
}
}
void Player::addStone(Stone& added) {
pie.addStone(added);
}
int main()
{
char name[80];
cout << "enter your name" << endl;
cin >> name;
Game game(name);
game.run();
}
Maybe change the "list" variable name to "list1" or something like that. "list" is a STL container, just like vector.

C++ code for inheritance breaks when trying to assign a value

I am trying to write this code where there are 2 classes inherited from a parent class.But this code breaks when I try to use it in a link list.Here is the code
class airship{
public:
airship(){};
// virtual ~ airship();
virtual void setData (string)=0;
virtual void showData()=0;
void setNext(airship* newptr);
airship* getNext();
void setType(int n){airshipType=n;}
int getType(){return airshipType;}
void setCount(int n){maxPassengerCount=n;};
int getCount(){return maxPassengerCount;}
void setWeight(int n){maxCargoWeight=n;}
int getWeight(){return maxCargoWeight;}
protected:
int maxPassengerCount;
int maxCargoWeight;
int airshipType;
private:
airship* next;
};
class airplane: public airship{
protected:
const char* airplaneName;
int engineType;
double range;
public:
airplane():airship(){};
// ~ airplane();
void setData(string);
void showData();
void setEngine(int n){engineType=n;}
int getEngine(){return engineType;}
void setRange(int n){range=n;}
int getRange();
};
class balloon : public airship{
protected:
const char* balloonName;
int gasType;
double maxAltitude;
public:
balloon():airship(){};
// ~balloon();
void setData(string);
void showData();
void setGas(int);
int getGas();
void setAlt(int);
int getAlt();
};
class mylist{
private:
airship* headAirship;
public:
void createlist(fstream&);
void setAirship(airship* Node){Node=headAirship;}
airship* getAirship(){return headAirship;}
};
void airship::setNext(airship* Node)
{
this->next=Node;
}
void airplane::setData(string line)
{
string line1;
bool flag=true;
int npos=0,nend,count=0;
while(line.c_str()!=NULL && flag)
{
nend=line.find(",",npos);
if (nend!=-1)
{
line1=line.substr(npos,nend);
}
else
{
line1=line;
flag=false;
}
line=line.substr(nend+1,line.length());
if (count==0)
this->airshipType=atoi(line1.c_str());
else if(count==1)
this->airplaneName=line1.c_str();
else if(count==2)
this->maxPassengerCount=atoi(line1.c_str());
else if(count==3)
this->maxCargoWeight=atoi(line1.c_str());
else if(count==4)
this->engineType=atoi(line1.c_str());
else
this->range=atoi(line1.c_str());
count=count+1;
}
}
void balloon::setData(string line)
{
string line1;
bool flag=true;
int npos=0,nend,count=0;
while(line.c_str()!=NULL && flag)
{
nend=line.find(",",npos);
if (nend!=-1)
{
line1=line.substr(npos,nend);
}
else
{
line1=line;
flag=false;
}
line=line.substr(nend+1,line.length());
if (count==0)
this->airshipType=atoi(line1.c_str());
else if(count==1)
this->balloonName=line1.c_str();
else if(count==2)
this->maxPassengerCount=atoi(line1.c_str());
else if(count==3)
this->maxCargoWeight=atoi(line1.c_str());
else if(count==4)
this->gasType=atoi(line1.c_str());
else
this->maxAltitude=atoi(line1.c_str());
count=count+1;
}
}
void mylist::createlist(fstream &myfile)
{
string ipdata;
int type;
while (getline(myfile,ipdata))
{
airship* newNode;
type=ipdata.find(",",0);
string ch=ipdata.substr(type-1,type);
if (atoi(ch.c_str())==0)
{
airplane* planeNode=new airplane();
planeNode->setData(ipdata);
newNode=planeNode;
}
else
{
balloon* balloonNode=new balloon();
balloonNode->setData(ipdata);
newNode=balloonNode;
}
newNode->setNext(headAirship);
this->headAirship=newNode;
}
}
int main()
{
mylist* list=0;
airship* firstNode=0,*otherNode=0;
/*if(argv[1]==NULL)
{
cout<<"File not Found"<<endl;
return -1;
}*/
fstream ipFile("data.txt",ios::in | ios::out);
if(ipFile.is_open())
{
list->createlist(ipFile);
}
list->setAirship(firstNode);
return 0;
}
The airplane::setdata(string) function does not work properly and it is not able to detect headAirship pointer in the createList function.And that is why I get a memory exception error in the createlist function when I try to do this:newNode->setNext(headAirship);
Unhandled exception at 0x00912ae0 in Assignment4Solution2.exe: 0xC0000005:
Access violation reading location 0x00000000.
I think the problem is here:
mylist* list=0;
In that line, you create a pointer to a myList object, but you don't make it point to any such object; it's pointing to address 0
Then you do
list->createlist(ipFile);
Since list is not pointing an address containing a myList object, invoking any of the myList methods is supposed to give the error you observed: Access violation reading location 0x00000000.
Instead, when you create the list pointer, invoke the constructor for myList so that the object gets created and the pointer is initialized to point to it
myList * list = new myList();
Hope that helps :)

Why isn't this typedef working

This code works if the 7th line down says "typedef char ItemType" but instead I made it typedef to the EventInfo object. The MSVS compiler says some really weird things...
error C2146: syntax error : missing ';' before identifier 'ItemType'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
But I don't understand why it works correctly when it is a char.
I know this is a lot of code but the typedef is on the 7th line. I included the whole thing because I don't know what to expect.
#include <iostream>
#include <cstdlib>
#include <fstream>
using namespace std;
const int MaxQueueSize = 8; // Queue Struct can hold up to 8
typedef EventInfo ItemType; // the queue's data type !DOES NOT COMPILE
enum EventType {Arrival, Depart};
class EventInfo
{
public:
EventInfo() : eTime(0), aTime(0), minutes(0) {}
int eventTime();
int duration();
void ScheduleEvent(int eTime, int duration);
bool compare(int eTime);
private:
int eTime; //either the arrival time of the next customer or the departure time of the customer currently at the teller window
int aTime; //either the service time for the arriving customer or the wait time for the customer at the teller window
float minutes;
};
int EventInfo::eventTime()
{
return this->eTime;
}
int EventInfo::duration()
{
return this->aTime;
}
void EventInfo::ScheduleEvent(int eTime, int duration)
{
this->eTime = eTime;
this->aTime = duration;
}
bool EventInfo::compare(int eTime)
{
return (eTime == this->eTime);
}
///////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////
//////////////////////////
////////////////
class CPPQueue
{
public:
CPPQueue() : front(0), rear(0), count(0) { };
ItemType item[MaxQueueSize];
bool IsEmpty() const;
bool IsFull() const;
void Enqueue(ItemType newItem);
void PrintQ();
void PrintQueueInfo();
ItemType Dequeue();
int Count();
private:
int front, rear;
int count;
};
bool CPPQueue::IsEmpty() const
{
return (this->count == 0);
}
bool CPPQueue::IsFull() const
{
return (this->count == MaxQueueSize);
}
void CPPQueue::Enqueue(ItemType newItem)
{
if(this->count == MaxQueueSize)
{
cerr << "Error! Queue is full, cannot enqueue item.\n" << endl;
exit(1);
}
this->item[this->rear] = newItem;
this->rear++;
if (this->rear == MaxQueueSize)
{
this->rear = 0; // adjustment for circular queue
}
this->count++;
}
ItemType CPPQueue::Dequeue()
{
ItemType theItem;
if(this->count == 0)
{
cerr << "Error! Queue is empty, cannot dequeue item.\n" << endl;
exit(1);
}
theItem = this->item[this->front ];
this->front++;
if (this->front == MaxQueueSize)
{
this->front = 0; // adjustment for circular queue
}
this->count--;
return theItem;
}
// Function PrintQ() prints the contents of the queue without changing
// the queue. Printing starts at the "front" index and stops before we
// get to the "rear" index. A decrementing counter controls the loop.
//
void CPPQueue::PrintQ()
{
int i;
int qindex = this->front;
for(i = this->count; i > 0; i--)
{
cout << this->item[qindex] ;
qindex = (++qindex) % MaxQueueSize; // adjustment for circular queue
if(i > 1)
cout << ", ";
}
}
// Helper function for the main program below.
void CPPQueue::PrintQueueInfo()
{
cout << "The queue contains: ";
PrintQ();
cout << endl;
}
int CPPQueue::Count()
{
return this->count;
}
enum TellerStatus {Idle, Busy};
class Teller
{
public:
Teller() : status(Idle), idleTime(0), totalIdleTime(0) {}
void changeStatus(TellerStatus status);
TellerStatus getStatus(void);
private:
TellerStatus status;
int idleTime; //!
int totalIdleTime; //!!
};
void Teller::changeStatus(TellerStatus status)
{
this->status = status;
}
TellerStatus Teller::getStatus()
{
return this->status;
}
class Bank
{
public:
Bank() : Clock(0.0) {}
void RunSimulation();
private:
EventInfo Event[2]; // array of two events - next arrival and next departure
CPPQueue WaitLine; // the customer wait line [with max size = 8]
float Clock; // to keep track of Current Bank Time
Teller theTeller; // the single teller in the bank
ifstream myfile;
void ProcessArrival(), ProcessDeparture(), PrintHeader(), PrintReportLine(), PrintStatsReport();
};
void Bank::RunSimulation()
{
}
void Bank::ProcessArrival()
{
int a, b;
string filename, x;
filename = "P3Data1.txt";
myfile.open(filename);
while (myfile >> a >> b)
{
Event[1].ScheduleEvent(a, b);
WaitLine.Enqueue(Event);
}
}
int main()
{
Bank myBank;
myBank.RunSimulation();
}
The name EventInfo is only usable from its point of declaration forward. Your typedef is too early, and the compiler doesn't yet know what a EventInfo is.
You can move the typedef below the class definition, or you can tell the compiler that EventInfo is a class:
typedef class EventInfo ItemType;
In C++, unlike in Java, you can only use names that have been declared earlier in the file. So just change the order:
class EventInfo { /* ... */ };
typedef EventInfo ItemType;
In fact, it's enough to just declare the class, if you don't want to define it just yet: class EventInfo;
Put the typedef after the class definition. You can't do typedef for unknown types.
First you need to forward declare class EventInfo;
Otherwise your typedef has no idea of what EventInfo is.
THen you have various problems, e.g. you need to overload << for EventInfo class etc.