Double astrisk syntax & Help calling member functions - c++

I'm working a program where there's an Airline class. The Airline class contains a vairable to an array of dynamic Flight objects.
In the Airlines class I have (which can't be edited or changed, this was the header file given to me for the assignment):
//Airline.h
class Airline {
public:
Airline(); // default constructor
Airline(int capacity); // construct with capacity n
void cancel(int flightNum);
void add(Flight* flight);
Flight* find(int flightNum);
Flight* find(string dest);
int getSize();
private:
Flight **array; // dynamic array of pointers to flights
int capacity; // maximum number of flights
int size; // actual number of flights
void resize();
};
//Flight.h
class Flight {
public:
Flight();
// Default constructor
Flight(int fnum, string destination);
void reserveWindow();
void reserveAisle();
void reserveSeat(int row, char seat);
void setFlightNum(int fnum);
void setDestination(string dest);
int getFlightNum();
string getDest();
protected:
int flightNumber;
bool available[20][4]; //only four seat types per row; only 20 rows
string destination;
};
I'm trying to impliment one of the find methods in the class.
for that, I have:
Flight* Airline::find(int flightNum){
bool found = false;
for(int i = 0; i < size; i++){
if(array[i].getflightNum() == flightNum){
found = true;
return array[i];
}
}
if(!found)
return 0;
}
// Return pointer to flight with given number if present, otherwise
// return 0.
But it's saying that I need a class type when trying to call the getFlightNum() method. I don't really understand the error. Am I not calling the method correctly? What is the correct syntax?

Since you are dealing with pointers instead of actual objects, try this:
if(array[i]->getflightNum() == flightNum){ // Notice I am using -> instead of .
found = true;
return array[i];
}

Related

Why is the content of my pointer to a friend class changing?

I am trying to create an object class "Bag" to store a linked list of object of friend class "Items".
Bag contains a pointer to an "Item" object.
The first call to the content of the Item object is always correct.
However, I am facing some problems as the value called subsequently will never be the same as the value called in the first time.
In other words,
Baseclass.BaseclassMember is constant as expected.
But (Baseclass.FriendClassPointer)->FriendClassMember is changing
Anyone knows why?
enum itemtype {potion, poison};
class Item
{
public:
friend class Bag;
Item(itemtype,int);
void initItem();
int qty;
int value;
Item *prevItem, *nextItem;
itemtype type;
};
class Bag
{
public:
Bag(Item,int);
Item *currentItem;
int currentsize;
int maxsize;
};
Item::Item(itemtype ITEMtype, int quantity): type(ITEMtype),qty(quantity)
{
initItem();
prevItem=nullptr;
nextItem=nullptr;
}
void Item::initItem()
{
value=8 ;
}
Bag::Bag(Item firstItem, int maxbagsize) : currentItem(&firstItem),maxsize(maxbagsize),currentsize(1)
{
currentItem->nextItem = currentItem;
currentItem->prevItem = currentItem;
cout<<"constructor check: Item Address "<<currentItem<<" nextAddress "<<currentItem->nextItem<<" "<<"\n";
}
int main()
Item item1(potion,1);
Bag bag1(item1,5);
cout<<" 1st call:"<<" Bagsize "<<bag1.currentsize<<" nextAddress "<<(bag1.currentItem)->nextItem<<"\n";
cout<<" 2nd call:"<<" Bagsize "<<bag1.currentsize<<" nextAddress "<<(bag1.currentItem)->nextItem<<"\n";
getchar(); /* stops window from closing */
return 0;

error: "EXC_BAD_ACCESS(code=EXC_I386_GPFLT)" when i try to insert class objects in array of class objects c++

So i have created a class that creates an array of objects from another class and when i try to execute the program and insert new objects to the array i get this error: EXC_BAD_ACCESS(code=EXC_I386_GPFLT)
Specifically on the insertion of the 10th element.
this is the class that has the array:
class Savelist{
private:
list_reserve *reserve;
list_user *users;
int length,MaxSize;
string code;
public:
string stoixeia;
Savelist(int MaxListSize)
{// Constructor for formula-based linear list.
MaxSize = MaxListSize;
reserve = new list_reserve (MaxSize, code);
users=new list_user(MaxSize);
length = 0;
}
~Savelist() {delete [] reserve,delete [] users;} // destructor
bool IsEmpty() const {return length == 0;}
int Length() const {return length;}
the method that inserts class objects to array:
void Insert_flight(list_reserve input)
{// "push" all objects one position up
if (length!=0)
{
for (int i=length-1; i >=0; i--)
{
reserve[i]=reserve[i+1];
}
reserve[0] = input;
length++;
}
else
{
reserve[0] = input;
length++;
}
}
here is the class that creates the objects that are being inserted to array:
class list_reserve {
private:
bool result;
int length,MaxSize;
string *object; // dynamic 1D array
public:
string code;
bool get_result;
// constructor
list_reserve(int MaxListSize,string flcode)
{// Constructor for formula-based linear list.
MaxSize = MaxListSize;
object = new string [MaxSize];
length = 0;
code=flcode;
}
~list_reserve() {delete [] object;} // destructor
bool IsEmpty() const {return length == 0;}
int Length() const {return length;}
the method that inserts simple strings to the object of that class:
void Insert_User(string input,string code,list_flight schedule)
{// Insert user
if (length!=0)
{
for (int i=length-1; i >=0; i--)
{
object[i+1] = object[i];
}
object[0] = input;
schedule.Get(code);
schedule.update(schedule.code, 1);
length++;
}
else
{
object[0] = input;
schedule.Get(code);
schedule.update(schedule.code, 1);
length++;
}
}
};
And lastly the main():
int main(int argc, const char * argv[]) {
list_reserve DA001_r(100,"DA001"),DA002_r(100,"DA002"),DA003_r(100,"DA003"),DA004_r(100,"DA004"),DA005_r(100,"DA005")
,DA006_r(100,"DA006"),DA007_r(100,"DA007"),DA008_r(100,"DA008"),DA009_r(100,"DA009"),DA010_r(100,"DA010"),DA011_r(100,"DA011")
,DA012_r(400,"DA012"),DA013_r(400,"DA013"),DA014_r(100,"DA014"),DA015_r(100,"DA015"),DA016_r(100,"DA016"),DA017_r(100,"DA017")
,DA018_r(100,"DA018"),DA019_r(100,"DA029"),DA020_r(100,"DA020"),DA021_r(100,"DA021"),DA022_r(100,"DA022"),DA023_r(400,"DA023"),
DA024_r(400,"DA024");
Savelist Queues(100);
Queues.Insert_flight(DA001_r);
Queues.Insert_flight(DA002_r);
Queues.Insert_flight(DA003_r);
Queues.Insert_flight(DA004_r);
Queues.Insert_flight(DA005_r);
Queues.Insert_flight(DA006_r);
Queues.Insert_flight(DA007_r);
Queues.Insert_flight(DA008_r);
Queues.Insert_flight(DA009_r);
Queues.Insert_flight(DA010_r);
Queues.Insert_flight(DA011_r);
Queues.Insert_flight(DA012_r);
Queues.Insert_flight(DA013_r);
Queues.Insert_flight(DA014_r);
Queues.Insert_flight(DA015_r);
Queues.Insert_flight(DA016_r);
Queues.Insert_flight(DA017_r);
Queues.Insert_flight(DA018_r);
Queues.Insert_flight(DA019_r);
Queues.Insert_flight(DA020_r);
Queues.Insert_flight(DA021_r);
Queues.Insert_flight(DA022_r);
Queues.Insert_flight(DA023_r);
Queues.Insert_flight(DA024_r);
}
You really, really don't want to store owning pointers to dynamically allocated resources in classes. For a good rundown on why see this answer on what's necessary to store an owning pointer in a class. Using a standard container such as std::vector also greatly simplifies the code as these implement most common operations you may want to do with them, such as insertion, deletion and the like.
For instance, your Savelist class would become the following when using std::vector
class Savelist {
private:
vector<list_reserve> reserve;
vector<list_user> users;
// No need for storing MaxSize or length, std::vector can store any
// number of elements, and knows how many elements it contains.
string code;
public:
string stoixeia;
// constructor and destructor becomes unnecessary, as the vector member
// takes care of all the bookkeeping
bool IsEmpty() const { return reserve.empty(); }
int Length() const { return reserve.size(); }
// Insert flight need only pass the input to the vector
void Insert_flight(list_reserve input) { reserve.insert(reserve.begin(), input); }
};
And similarly for the list_reserve class
class list_reserve {
private:
bool result;
// once again, the vector keeps track of size and elements contained
vector<string> object;
public:
string code;
bool get_result;
// constructor becomes simpler
list_reserve(string flcode)
{
code = flcode;
}
// destructor becomes unnecessary
bool IsEmpty() const { return object.empty(); }
int Length() const { return object.size(); }
void Insert_User(string input, string code, list_flight schedule)
{
// note that object.push_back(input); would be
// more efficient, but inserts the element at the end.
object.insert(object.begin(), input);
schedule.Get(code);
schedule.update(schedule.code, 1);
}
};
See also cppreference page on std::vector for an excellent reference on what's available.

How do I use integers and floats within an object correctly?

So I'm trying to write a program that keeps track of various attributes of wineries that has the following attributes.
-Dynamically allocated memory
-Integers to keep track of the year the winery started
-Floats for the success rating and acres of land the vineyards take up.
-Functions to add, remove, display (by rating and by name), and save the winery data.
I've already written/debugged code to work with a similar program where all the attributes were cstrings, and this code is based off the same framework.
My problem is that the same code that works for dynamically allocated cstrings doesn't work with integers or floats and I'm getting conversion error messages from the compiler. I have a list class that contains aWinery and since I'm using private members to hide the data I have functions to pass from the client program into the list and into aWinery. The functions with the same types are identical so I only include one of each type here.
Could someone point out what I'm doing wrong? I don't know how I would return through the parameters if aWinery's definition of the int and floats were not pointers. The only examples of dynamic memory programming I can find with classes use cstrings. I've noted a couple points in the code that I copied from an instructor because I couldn't figure it out.
EDIT: the specific error I'm getting is invalid conversion from int* to int\n year = this->year which some permutation of occurs in all of the aWinery's integer and float based accessor and mutator functions.
List Accessor, Mutator, Constructor, and Destructor functions
void list::getWineryLocation(char location[]) const
{
wineryData.getLocation(location);
}
void list::getWineryYear(int year) const
{
wineryData.getYear(year);
}
void list::getWineryAcres(float acres) const
{
wineryData.getAcres(acres);
}
void list::setWineryLocation(char location[])
{
wineryData.setLocation(location);
}
void list::setWineryYear(int year)
{
wineryData.setYear(year);
}
void list::setWineryAcres(float acres)
{
wineryData.setAcres(acres);
}
//Constructor functions
list::list()
{
nameHead = NULL;
nameTail = NULL;
ratingHead = NULL;
ratingTail = NULL;
size = 0;
}
//Destructor
//Doesn't delete the head/tailRating pointers to avoid double deleting a winery
list::~list()
{
node * curr = nameHead;
while (nameHead != NULL)
{
curr = nameHead->nextByName;
delete nameHead;
nameHead = curr;
}
}
aWinery Accessor, Mutator, Constructor, and Destructor functions
//Winery object constructor
aWinery::aWinery()
{
name = new char[strlen("Unknown")+1];
strcpy(name, "Unknown");
location = new char[strlen("Unknown")+1];
strcpy(location, "Unknown");
year = new int;
year = 0;
acres = new float;
acres = 0;
successRating = new float;
successRating = 0;
}
//I have no idea whats going on here
//Winery destructor
aWinery::~aWinery()
{
if(name != NULL)
delete [] name;
if(location != NULL)
delete [] location;
if(year != 0)
delete year;
if(acres != 0)
delete acres;
if(successRating != 0)
delete successRating;
}
void aWinery::getLocation(char location[]) const
{
strcpy(location, this->location);
}
void aWinery::getYear(int year) const
{
year = this->year;
}
void aWinery::getAcres(float acres) const
{
acres = this->acres;
}
//I have no idea why this is written this way, I copied this from an instructor example
void aWinery::setLocation(char location0[])
{
if(this->location != NULL)
delete [] this->location;
this->location = new char[strlen(location0)+1];
strcpy(this->location, location0);
}
void aWinery::setYear(int year0)
{
if(this->year != 0)
delete this->year;
this->year = new int;
this->year = year0;
}
void aWinery::setAcres(float acres0)
{
if(this->acres != 0)
delete this->acres;
this->acres = new float;
this->acres = acres0;
}
aWinery header file
#ifndef AWINERY_H
#define AWINERY_H
#include <iostream>
using namespace std;
//winery object
class aWinery
{
public:
//Constructor
aWinery();
//Destructor
~aWinery();
//Accessor Prototypes
void getName(char name[]) const;
void getLocation(char location[]) const;
void getYear(int year) const;
void getAcres(float acres) const;
void getSuccessRating(float successRating) const;
//Mutator Prototypes
void setName(char name0[]);
void setLocation(char location0[]);
void setYear(int year0);
void setAcres(float acres0);
void setSuccessRating(float successRating0);
private:
char* name;
char* location;
int* year;
float* acres;
float* successRating;
};
#endif
list header file
#ifndef ALIST_H
#define ALIST_H
#include <iostream>
using namespace std;
const int MAX_CHAR_LENGTH = 1000;
class list
{
public:
//Prototypes
void setInWinery(char name[], char location[], int year, float acres, float successRating);
void initializeDbase(char savePathName[]);
void printEntireDbase();
void deleteWinery(char nameOfWinery[]);
void whereIsWinery(char nameOfWinery[]);
void save(char savePathName[]);
//Accessor Prototypes
void getWineryName(char name[]) const;
void getWineryLocation(char location[]) const;
void getWineryYear(int year) const;
void getWineryAcres(float acres) const;
void getWinerySuccessRating(float successRating) const;
int getSize() const;
//Mutator Prototypes
void setWineryName(char name[]);
void setWineryLocation(char location[]);
void setWineryYear(int year);
void setWineryAcres(float acres);
void setWinerySuccessRating(float successRating);
//Constructor Prototype
list();
//Destructor
~list();
private:
//Wine object
struct node
{
aWinery wineryData;
node * nextByName;
node * nextByRating;
};
node * nameHead, * nameTail, * ratingHead, * ratingTail;
aWinery wineryData;
int size;
};
#endif
I think the bulk of your problem is in the header, here:
private:
char* name;
char* location;
int* year;
float* acres;
float* successRating;
There's really no reason to use pointers for any of these member variables; you might as well make them all plain-old by-value members, like this:
private:
std::string name;
std::string location;
int year;
float acres;
float successRating;
Note that I replaced the (char *) member variables with std::string, since in a C++ program there's really no reason not to use a proper string object. (Using dynamically allocated char arrays to hold character strings might be a necessary evil if you're writing in C, but in C++ it's just masochism)
By storing all of your data by-value, you can get rid of all of the new and delete commands (and the inevitable bugs and inefficiency that come with them) and just set and get the values directly when necessary.
Also, this accessor function is wrong:
void aWinery::getYear(int year) const
{
year = this->year;
}
It won't work because in C++, method parameters are (by default) passed by value (i.e. a temporary local copy of the passed-in value is made, for the method to use), so all the above method does is modify the local parameter year, which is then immediately destroyed as soon as the function returns. A proper accessor method would look more like this:
int aWinery::getYear() const
{
return this->year; // assuming year member variable is now of type int
}
.... and similarly, the setter method should look like this:
void aWinery::setYear(int newYear)
{
this->year = newYear; // assuming year member variable is now of type int
}

C++ dynamically increase array size for object-array?

I'm making a game with cocos2d-x. The different objects in the game i want to store in a class (I dont know if this is a good idea, but so i can give every object a lot of attributes). Then i make an array out of the objects and for that i need an own datastructure, where i can push and pop my objects. I tried to write this datastructure, but i think i doing wrong with my push function (i want to dynamically increase array size), especially the delete []? Doesn't that destroy my object-pointers stored?
ObjectArray.h:
#pragma once
#include "C:\Cocos\Projects\FirstGame\proj.win32\anObject.h"
class ObjectArrayList
{
public:
ObjectArrayList(int c);
ObjectArrayList();
virtual ~ObjectArrayList(void);
void push(anObject *obj);
void pop(int id);
int findIndex(int id);
int getSize();
int getCapacity();
private:
int capacity;
int size;
anObject **objectList;
};
ObjectArray.cpp:
#include "ObjectArrayList.h"
#include <iostream>
using namespace std;
objectArrayList::ObjectArrayList(int c)
{
size=0;
capacity = c;
objectList = new anObject*[capacity];
}
ObjectArrayList::ObjectArrayList() {
}
ObjectArrayList::~ObjectArrayList(void) {
}
void ObjectArrayList::push(anObject *obj) {
if(size < capacity) {
} else {
int newCap = 2*capacity;
anObject **tmpObjectList = new anObject*[newCap];
for(int i = 0;i<capacity;i++) {
tmpObjectList[i] = objectList[i];
}
delete [] objectList;
objectList = tmpObjectList;
capacity = newCap;
}
objectList[size] = obj;
size++;
}
void ObjectArrayList::pop(int id) { //not finish yet
if(size != 0) {
size--;
}
}
int ObjectArrayList::findIndex(int id) {
return id;
}
int ObjectArrayList::getSize() {
return size;
}
int ObjectArrayList::getCapacity() {
return capacity;
}
anObject.h:
#pragma once
#include "cocos2d.h"
class anObject
{
public:
anObject(int hp_init, int x, int y);
anObject();
virtual ~anObject(void);
void decreaseHp();
int getHp();
void setMyPosition(int x, int y);
cocos2d::Sprite *getMySprite();
private:
cocos2d::Sprite *mySprite;
int hp;
int midX;
int midY;
int isX;
int isY;
};
Bert
As the comments pointed out... you should save some time and energy and try to use the Standard Template Library (STL).
If you insist on fixing this code, I think you should try referencing objectlist after the delete to see if it's still there... maybe this assignment...
objectList = tmpObjectList;
...is not tolerated.
Instead... try to build a copy constructor "public Object(Object copiedObject){}", make a new Object*[] of the 2X size, populate it, then get rid of the old and... without deleting objectList assign your new Object*[] to it...
The rest seems fine to me... hope this helps.
delete [] objectList;
This only frees the array which objectList points to. It does not free any of the objects in that array.

C++: how to get element defined in a different function of same class?

I defined a class in the header file like this:
class myClass
{
public:
void test();
void train();
private:
bool check;
}
Then in the cpp file, I did this:
void myClass::test()
{
int count = 9;
//some other work
}
void myClass::train()
{
int newValue = count;
....
}
Then without surprise, I got an error saying count is not defined. So what I want to do is in my train function use the count value that is defined in the test. Is there any good way to do this without using any additional dependencies? Thank you.
Well yes. That's called a member variable. Exactly like your bool check;.
Do
private:
bool check;
int count;
and then use it directly in your functions.
void myClass::test()
{
count = 9;
//Same as this->count = 9;
}
void myClass::train()
{
int newValue = count;
//Same as int newValue = this->count;
}
In your example, when method test finishes its work, count variable does not exist anymore, so there's no way of accessing it. You have to ensure, that its lifetime will be long enough to be accessed from another place. Making it a class field solves the problem (this is what class fields are for :)).
Do it this way:
class myClass
{
public:
void test();
void train();
private:
bool check;
int count; // <- here
}
and then
void myClass::test()
{
count = 9;
//some other work
}
But that's not the only solution. You can do it in another way, say:
class myClass
{
public:
int test()
{
// do some work
return 9;
}
void train(int count)
{
int newValue = count;
}
}
// (somewhere)
myClass c;
int count = c.test();
c.train(count);
That all depends on what test, train and count are for...