How to access member function of one class inside another class? - c++

I am unable to access a member function of one class inside another, though I can access it fine in main(). I've been trying to switch things around, but am unable to understand what am I doing wrong. Any help would be appreciated.
Here is the line that generates the error:
cout << "\n\nRetrieve key from inside Envelope class: " << e.getData() << "\n\n";
And here is the code:
class Record{
private:
string key;
public:
Record(){ key = ""; }
Record(string input){ key = input; }
string getData(){ return key; }
Record operator= (string input) { key = input; }
};
template<class recClass>
class Envelope{
private:
recClass * data;
int size;
public:
Envelope(int inputSize){
data = new recClass[inputSize];
size = 0;
}
~Envelope(){ delete[] data; }
void insert(const recClass& e){
data[size] = e;
cout << "\n\nRetrieve key from inside Envelope class: " << e.getData() << "\n\n";
++size;
}
string getRecordData(int index){ return data[index].getData(); }
};
int main(){
Record newRecord("test");
cout << "\n\nRetrieve key directly from Record class: " << newRecord.getData() << "\n\n";
Envelope<Record> * newEnvelope = new Envelope<Record>(5);
newEnvelope->insert(newRecord);
cout << "\n\nRetrieve key through Envelope class: " << newEnvelope->getRecordData(0) << "\n\n";
delete newEnvelope;
cout << "\n\n";
return 0;
}

You are passing e as a constant reference void insert(const recClass& e){
And then you are calling a method (getData()) not declared as constant.
You can fix it by rewriting getData() like this:
string getData() const{ return key; }

You have to declare getData() as const so it can be called from a const context. Your insert function take a const recClass& e so you want to do this in Record:
string getData() const { return key; }

Related

Is it possible to use same functions for every class

I have multiple classes and each of them has their own methods. All of these methods perform the same task, as you can see in my code. The only unique thing is the values of the title, code and credit members that are defined inside the classes.
Is there a way to write this code such that a single set of methods can do the required tasks (using the specific values within the class that made the request to the method) for each and every class?
I'm a university student, and due to this I don't want to use inheritance since we haven't learned it yet.
class seng305
{
string title = "Software design and architecture", code = "SENG305";
int credit = 4;
public:
seng305();
~seng305();
string get_info();
string get_title();
int get_credit();
};
class comp219
{
string title = "Electronics in computer engineering", code = "COMP219";
int credit = 4;
public:
comp219();
~comp219();
string get_info();
string get_title();
int get_credit();
};
seng305::seng305()
{
cout << '\t' << "Created" << endl;
}
seng305::~seng305()
{
cout << '\t' << "Destroyed" << endl;
}
string seng305::get_info()
{
return (code + "-" + title);
}
string seng305::get_title()
{
return title;
}
int seng305::get_credit()
{
return credit;
}
//--------------------------------------------------
comp219::comp219()
{
cout << '\t' << "Created" << endl;
}
comp219::~comp219()
{
cout << '\t' << "Destroyed" << endl;
}
string comp219::get_info()
{
return (code + "-" + title);
}
string comp219::get_title()
{
return title;
}
int comp219::get_credit()
{
return credit;
}
As you can see, the get_info(), get_title(), and get_credit() methods do the same thing.
I would like for a single get_info(), get_title(), get_credit() to be able to do the task for each class.
There is no reason to use separate classes at all in this example. A single class will suffice, eg:
class course
{
string title, code;
int credit;
public:
course(const string &title, const string &code, int credit);
~course();
string get_info() const;
string get_title() const;
int get_credit() const;
};
course::course(const string &title, const string &code, int credit)
: title(title), code(code), credit(credit)
{
cout << '\t' << "Created" << endl;
}
course::~course()
{
cout << '\t' << "Destroyed" << endl;
}
string course::get_info() const
{
return (code + "-" + title);
}
string course::get_title() const
{
return title;
}
int course::get_credit() const
{
return credit;
}
Then, you simply create instances of your class as needed, eg:
course seng305("Software design and architecture", "SENG305", 4);
course comp219("Electronics in computer engineering", "COMP219", 4);
...
I know you said that you don't want to use inheritance, but that could be the next logical step, using the above code as a base:
class courseSeng305 : public course
{
public:
courseSeng305() : course("Software design and architecture", "SENG305", 4) {}
};
class courseComp219 : public course
{
public:
courseComp219() : course("Electronics in computer engineering", "COMP219", 4) {}
};
courseSeng305 seng305;
courseComp219 comp219;
...

How to print a value returned by a class method

I am having troubles printing a value returned by a class method. In the DataClass instance, cout will print the dataMember (an int) using a statement of the form:
cout << dataClassInstance.getDataMember();
However the ListEntry, which contains a DataClass as a member, is unable to print that same value using its own function. The Form is:
cout << listEntryInstance.getDataClass();
ListEntry uses its own get function which calls the DataClass's get function to return the same int value but it gives an error instead:
[Error] no match for 'operator<<' (operand types are
'std::basic_ostream' and 'DataClass')
Any ideas on what I'm doing wrong would be much appreciated. I can't seem to find any solutions from what I've looked at so far.
class DataClass
{
private:
dataType dataMember;
public:
//default
DataClass()
{
dataMember;
}
//parameterized
DataClass(dataType inputData)
{
dataMember = inputData;
}
//copy
DataClass(const DataClass &inputData)
{
dataMember = inputData.dataMember;
}
//destructor
~DataClass()
{
}
//set
void setData(dataType inputData)
{
dataMember = inputData;
}
//get
dataType getDataMember()
{
return dataMember;
}
};
class ListEntry
{
private:
DataClass data;
ListEntry* nextEntryPtr;
ListEntry* prevEntryPtr;
public:
//default
ListEntry() : data()
{
nextEntryPtr = NULL;
prevEntryPtr = NULL;
}
//parameterized
ListEntry(const DataClass& inputData) : data(inputData)
{
nextEntryPtr = NULL;
prevEntryPtr = NULL;
}
//copy
ListEntry(const ListEntry& entryToCopy) : data(entryToCopy.data)
{
nextEntryPtr = NULL;
prevEntryPtr = NULL;
}
//destructor
~ListEntry()
{
}
//set
void setDataClass(DataClass dataInput)
{
data.setData(dataInput.getDataMember());
}
void setNextEntry(ListEntry* entryPtr)
{
nextEntryPtr = entryPtr;
}
void setPrevEntry(ListEntry* entryPtr)
{
prevEntryPtr = entryPtr;
}
//get
DataClass getDataClass()
{
return data.getDataMember();
}
ListEntry* getNextEntry()
{
return nextEntryPtr;
}
ListEntry* getPrevEntry()
{
return prevEntryPtr;
}
};
Sample of the code I'm using to test the functionality of each class. DataClass gives the expected results, ListEntry only gives an error.
//STUB TEST FOR DATACLASS
dataType constructTest = 42;
cout << "Creating DataClass with default constructor."
<< endl;
DataClass defaultTestData; //default initialize
cout << "Value held in DataClass: "
<< defaultTestData.getDataMember()
<< endl << endl;
//STUB TEST FOR LISTENTRY
cout << "Creating list entry with default constructor." << endl;
ListEntry defaultEntry;
cout << "Value held in list entry:"
<< defaultEntry.getDataClass()
<< endl << endl;
You are trying to print a DataClass, not a member of it. For this class, you have not specified how to print it (by overloading the << operator). That is what the compiler is complaining about.
What you want is probably
cout << listEntryInstance.getDataClass().getDataMember();
Stream insertion operator isn't overloaded for DataClass
friend std::ostream &operator<<(std::ostream &out, const DataClass &dc) {
out << dc.dataMember;
return out;
}

Concept of data storing in c++

I have a Spieler class and a Verein class with a vector of Spieler members.
Now if I change something of the Players like the Staerke(german for strength) by using a function of this class in the player class it does not automatically change the value for this player.
Here is the code:
#include <vector>
#include<iostream>
#include <string>
using namespace std;
class Spieler
{
public:
void setinformation(int a, string b, string c, int d)
{
ID = a;
Vorname = b;
Nachname = c;
Staerke = d;
}
void getinformation()
{
cout << "ID: " << ID << endl;
cout << "Vorname: " << Vorname << endl;
cout << "Nachname: " << Nachname << endl;
cout << "Staerke: " << Staerke << endl << endl;
}
void setStaerke(int x)
{
Staerke = x;
}
int getStaerke()
{
return Staerke;
}
private:
string Vorname, Nachname;
int Staerke, ID;
};
class Verein
{
public:
void setSpielerListe(vector<Spieler> x)
{
Spielerliste = x;
}
vector<Spieler> getSpielerListe()
{
return Spielerliste;
}
string getVereinsName()
{
return VereinsName;
}
int getVereinsID() const
{
return VereinsID;
}
void setVereinsID(int x)
{
VereinsID = x;
}
int getGesamtstaerke()
{
Gesamtstaerke = 0;
vector<Spieler> b;
b = getSpielerListe();
for (size_t i = 0; i < b.size(); i++)
{
Gesamtstaerke = Gesamtstaerke + b[i].getStaerke();
}
return Gesamtstaerke;
}
void Vereinsinformationen()
{
vector<Spieler> list;
int id;
string vereinsname;
int gesamtstaerke;
id = getVereinsID();
vereinsname = getVereinsName();
gesamtstaerke = getGesamtstaerke();
list = getSpielerListe();
cout << "VereinsID: " << id << endl;
cout << "Vereinsname: " << vereinsname << endl;
cout << "Gesamstaerke: " << gesamtstaerke << endl << endl;
cout << "Spieler: " << endl;
for (size_t i = 0; i < list.size(); i++)
list[i].getinformation();
}
private:
vector<Spieler> Spielerliste;
int VereinsID, Gesamtstaerke;
string VereinsName;
};
vector<Spieler> spieler;
int main()
{
Spieler Spieler1;
Spieler1.setinformation(0, "Peter", "Pan", 10);
spieler.emplace_back(Spieler1);
Verein Team1;
Team1.setSpielerListe(spieler);
Spieler1.setStaerke(20);
Team1.Vereinsinformationen();
cin.get();
return 0;
}
I'm really new into c++ and programming so the code might be terrible.
Guess it has to do with pointers, I'm really not into the concept of storing data in c++, try to get it by trial & error; So how to change the Staerke in a way that it is changed in the Teams Playerlist too?
The problem is you are storing full object in the vector and not pointers. When you run this line:
spieler.emplace_back(Spieler1);
a copy of Spieler1 is made and put in the vector. So modifying it in the main will have no effect in the vector. Also not that you are copying the vector when setting in Verein class.
You should use pointer if this is what you are after or better yet have a function to modify strength from Verein class taking its id and new strength as parameters might be a good idea. Something like this:
void setStaerke(int id, int x)
{
vector<Spieler>::iterator it = Spielerliste.begin();
while (it != Spielerliste.end())
{
if ((*it).GetId() == id)
{
(*it).setStaerke(x);
break;
}
}
}
If you have access to C++11, it could be made more elegantly.
Hereby you pass and store a copy from the vector into the object:
Team1.setSpielerListe(spieler);
Therefore changes to the original vector and the contained objects will not affect the member.
Further, I don't have much experience with emplace_back, but the more usual way to append an object to a std::vector would also append a copy:
spieler.push_back(Spieler1);
Therefore changes to the original object would not affect the object you've appended to the container.
Make sure you better understand when objects are copied.
For reference:
http://en.cppreference.com/w/cpp/container/vector/emplace_back
http://en.cppreference.com/w/cpp/container/vector/push_back
How to pass objects to functions in C++?

C++ string member variable not present in vector

I am creating a vector that contains pointers to a base class. In this vector I'm dynamically storing pointers to derived classes which contain some member variables, one of them being a string variable name.
#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
bool hasDirection = false;
bool hasDiameter = false;
int direction;
float diameter;
int starDimension = 0;
int animalDimension = 0;
int fishDimension = 0;
class MovingObject
{
protected:
std::string name;
int direction;
float diameter;
int dimension;
float movingSpeed;
public:
std::string getName(){ return name;};
int getDirection(){ return direction;};
float getDiameter(){ return diameter;};
float getMovingSpeed(){ return movingSpeed;};
int getDimension(){ return dimension;};
void setName(std::string v){ name = v;};
void setDirection(int d){ direction = d;};
void setDiameter(float f){ diameter = f;};
void setMovingSpeed(float s){ movingSpeed = s;};
void setDimension (int d){ dimension = d;};
virtual void PrintContents()=0;
};
static std::vector<MovingObject*> data;
class starObject : public MovingObject
{
public:
void PrintContents()
{
std::cout << "(" << getName() << "," << getDiameter() << "," << getDirection() << ")";
}
};
class animalObject : public MovingObject
{
public:
void PrintContents()
{
std::cout << "(" << getName() << "," << getDiameter() << "," << getDirection() << ")";
}
};
class fishObject : public MovingObject
{
public:
void PrintContents()
{
std::cout << "(" << getName() << "," << getDiameter() << "," << getDirection() << ", [" << getDimension() << "], " << getMovingSpeed() << ")";
}
};
I later set all these member variables inside a main function. The problem is when I try to output the contents of the member variables, all of them show up except for the string name.
Now, I've checked to make sure that the string gets set before calling the PrintContent() method, and it shows that the value is in the vector. However, when I debug through the code, the value is no longer there, instead containing an empty string.
Could someone with better c++ knowledge explain to me why this is happening? This is the main class:
int main()
{
std::string type;
Reader reader;
while (!std::cin.eof())
{
try
{
std::string type;
std::cin >> type;
if (type =="int")
{
reader.ReadDirection();
}
else if (type =="float")
{
reader.ReadDiameter();
}
else if (type == "string")
{
std::string name;
std::cin >> name;
if (hasDirection && hasDiameter)
{
int dimension;
if (diameter > 0 && diameter < 10)
{
//fish
fishObject fish;
fish.setName(name);
fish.setDiameter(diameter);
fish.setDirection(direction);
dimension = fishDimension;
fishDimension += 50;
fish.setDimension(dimension);
fish.setMovingSpeed(0.1);
data.push_back(&fish);
}
else if (diameter >= 10 < 500)
{
//animal
animalObject animal;
animal.setName(name);
animal.setDiameter(diameter);
animal.setDirection(direction);
dimension = animalDimension;
animalDimension += 800;
animal.setDimension(dimension);
animal.setMovingSpeed(5.0);
data.push_back(&animal);
}
else if (diameter >=500)
{
//star
starObject star;
star.setName(name);
star.setDiameter(diameter);
star.setDirection(direction);
dimension = starDimension;
starDimension += 5000;
star.setDimension(dimension);
star.setMovingSpeed(30.0);
data.push_back(&star);
}
}
else
{
throw (IncompleteData(name));
}
}
}
catch (IncompleteData e)
{
std::cerr << "No diameter or direction given for object " << e.objectName << "\n";
}
}
The objects you push to the data vector are local because they are declared inside if/else blocks (see the declarations of fish and animal).
When you push the address of such an object to the vector, it will continue to point to the local object, which ceases to exist at the end of the local scope. You need to create objects that live beyond the local scope. One way of doing this is to create copies of the local objects on the heap and push those to the vector:
data.push_back(new fishObject(fish));
Of course this means that you get a memory leak unless you make sure you explicitly delete the elements of the vector some time before the end of the program. The usual recommendation to avoid having to think of this is to use a vector of std::unique_ptr<MovingObject> instead of a vector of naked pointers.

can not change an object's property within another object in C++

I have the following code written in C++:
#include<iostream>
#include<vector>
using namespace std;
class cViews {
string viewName;
double minD;
vector<double> dss;
public:
string minInput1, minInput2;
cViews(string);
cViews();
void setName(string s) { viewName = s; }
string getName() { return viewName; }
void setMinI(string m) { minInput1 = m; }
string getMinI() { return minInput1; }
void setMinD(double d) { minD = d; }
double getMinD() { return minD; }
void addD(vector<double> k){ dss = k; }
vector<double> getD(){ return dss; }
};
cViews::cViews(string str) {
viewName = str;
vector<double> dss = vector<double>();
}
cViews::cViews() {
vector<double> dss = vector<double>();
}
class Obj{
string name;
cViews dist;
public:
Obj(string);
void setName(string s) { name = s; }
string getName() { return name; }
void addDist(cViews k){ dist = k; }
cViews getDist(){ return dist; }
};
Obj::Obj(string str) {
name = str;
cViews dist();
}
void changeViewN(cViews *v, string s){
v->setMinI(s);
}
int main(){
Obj o1("Object1");
cViews v3;
cViews v1("View 1");
v1.setMinI("View 2");
v1.setMinD(1);
o1.addDist(v1);
cout << o1.getName() << " " << o1.getDist().getMinI() << endl;
v3 = o1.getDist();
changeViewN(&v3, "Changed");
cout << o1.getName() << " " << o1.getDist().getMinI() << endl;
return 0;
}
Output is:
Object1 View 2
Object1 View 2
The problem here is I am trying to change the value of an object that was created within another object.
Output should be:
Object1 View 2
Object1 Changed
Any help is greatly appreciated. Thank you.
To change the object and not a copy, ou have to use pointers or references. Else you just copy the object returned from getDist() and thus cant change the original object.
cViews* getDist(){ return &dist; }
...
changeViewN(o1.getDist(), "Changed");
It seems you got a couple of problems, the first few:
cViews::cViews(string str) {
vector<double> dss = vector<double>();
}
viewName isn't initialized, dss is Declared in the function (which is meaningless as it will be scrapped as soon as the function returns).
ps. you would like to change the second line like this:
cout << o1.getName() << " " << o1.getDist().getMinI() << endl;
to
cout << o2.getName() << " " << o2.getDist().getMinI() << endl;
You should really proofread your code ...