I am currently working on a small game manager for my young nephews games, mainly as a project for me to learn C++.
It involves him inputting when he wants to move a model in his toy town he sets up on the carpet. The program then instantiates an object and asks my nephew to name the object (and he would then stick a sticker with that same name on the toy). It has to be this way because the names change each time he sets up his toy town (which is also subject to random dinosaur attacks). The program will then give a randomEvent (ie a task the toy must do and my nephew would move the toy etc). This code is a cut down version and it should be noted that there could possibly be a hundred (I hope not... but...) inherited classes derived from three base classes (Car, Houses, and People). In this example there are only People class and two derived classes, Shopowners and Policemen. There would be of course MANY more. My nephew is already lining them up for processing on the table...
It works so far except for the datafunc. This function processes the requested input and passes the appropriate class pointer to the randomEvents function. This is NOT happening. It only sends the policemen. Anyway, here is the code and any help will be appreciated. Thank you.
#include <iostream>
#include "cstdio"
#include <cctype>
#include <ctime>
#include <string>
class People {
public:
People():
attribute (0)
{}
int attribute;
void setId(std::string tag) { id = tag; }
static std::string getid() { return id; }
protected:
static std::string id;
};
std::string People::id = "Shopowners ";
class Shopowners : public People {
public:
Shopowners()
{
attribute = 25;
id;
}
};
class Policemen : public People {
public:
Policemen()
{
attribute = 13;
id;
}
};
void selection();
void datafunc();
void shops();
void cops();
int renadomEvents();
void move()
{
char yesno = 'y';
std::cout << "If you want to move a car or person does it have a name-sticker on it? y/n \n";
std::cin>>yesno;
if (yesno=='y') {datafunc();}
else selection();
}
void selection()
{
int choice;
std::cout<<" Which toy do you want to move?\n";
std::cout<< " 1. A shopowner.\n";
std::cout<< " 2. A policeman.\n";
std::cout<< " 3. A car.\n";
std::cin>> choice;
switch (choice){
case 1: shops();
break;
case 2: cops();
break;
//case 3 / 4 ,5 ...2043 etc. split up into sub menus
}
}
void shops()
{
std::string name;
std::cout << "Enter the name you want to give him.\n";
std::cin.ignore(256, '\n');
std::getline (std::cin, name);
Shopowners ownerOne; ownerOne.setId (name);
datafunc();
}
void cops()
{
std::string name;
std::cout << "Enter the name you want to give him. \n";
std::cin.ignore(256, '\n');
std::getline (std::cin, name);
Policemen copperOne; copperOne.setId (name);
datafunc();
}
void randomEvents (People &personA)
{
std::cout << personA.attribute<<"\n\n"; //currently prog should end here with print out of attribute
}
void datafunc ()
{
std::string idtag;
std::cout<< "Type in the name on the sticker. \n";
std::getline (std::cin, idtag);
People* people = NULL;
//skipping this line below??????????
if(idtag == Shopowners::getid()) {people = new Shopowners();}
//the line below is taking precedence!!!
if(idtag == Policemen::getid()) {people = new Policemen();}
randomEvents(*people);
}
int main()
{
move();
// other functions in gameloop
system ("pause");
return 0;
}
You've made id a static. This means that ALL classes share one instance of the variable. I think you intended each class to have it's own copy, which means it should not be static.
Anyway, your program has memory leaks because you aren't deleteing the memory you new.
Also, your objects aren't ever saved since they are local to the functions (meaning they are destroyed when the function exits). You'll need to have a vector or something similar to hold all the people (and a separate one for cars, etc).
I would also suggest moving your classes into separate files so that the code looks cleaner.
I probably missed some stuff but its late here so don't blame me XD
Removed the static and now cannot access non-static functions. Doesn't make any sense to me why they cant be accessed??
Actually frustrating to learn now, after all the class hype and OOP and inherited classes, to learn that the instance only has a lifetime of the function it was created in. I have to ask, what exactly is the point of that? When I first read about classes and derived classes I thought excellent, fits perfectly with all the projects I want to do. Now it seems all subject to obscure limitations and rules. I mean the above project should not really be that hard, especially after learning classes, pointers, references, derived classes. There must be lots of users requiring programs in which their own external input is required, cataloging, inventories etc.
Ah, that's because you have your getid function as a static function. Make it a non-static as well.
OOP is basically just a way to model your problem with a custom object. It has the same restrictions as other variables.
Anyway, that's just how scopes work. For example:
1 2 3 4 5 6 7 8 9 10 11 12
void myfunc() {
Object some_obj; //this is a scope
}
int main() {
myfunc();
//some_obj doesn't exist here
//if it did...what if I did this:
myfunc();
//now which obj exists? They have the same name
return 0;
}
If you want to be able to use an object elsewhere, you must store it in an different, more global object or return a value.
Yep made the getid function non static . Several errors appear which means removing line 21 and making dot operators in line 128 and 131 and I still get 6 errors 'left of getid' must have class/struct/union' These being shopowners or policemen and I could have sworn that that was exactly what they were?
'Illegal use of this type as an expression' Not sure what this is about but it refers again to shopowners and policemen. The compiler error 2275 tells me to use -> which when I do brings on several more errors, really piling them on now.
And the really good one = a nonstatic member reference must be relative to a specific object.'
Again I thought the member reference was an object??
#include <iostream>
#include "cstdio"
#include <cctype>
#include <ctime>
#include <string>
class People {
public:
People():
attribute (0)
{}
int attribute;
void setId(std::string tag) { id = tag; }
std::string getid() { return id; }
protected:
std::string id;
};
//std::string People::id = "Shopowners ";
class Shopowners : public People {
public:
Shopowners()
{
attribute = 25;
attributeB = 44;
id;
}
};
class Policemen : public People {
public:
Policemen()
{
attribute = 13;
attributeC = 55;
id;
}
};
void selection();
void datafunc();
void shops();
void cops();
int randomEvents();
void move()
{
char yesno = 'y';
std::cout << "If you want to move a car or person does it have a name-sticker on it? y/n \n";
std::cin>>yesno;
if (yesno=='y') {datafunc();}
else selection();
}
void selection()
{
int choice;
std::cout<<" Which toy do you want to move?\n";
std::cout<< " 1. A shopowner.\n";
std::cout<< " 2. A policeman.\n";
std::cout<< " 3. A car.\n";
std::cin>> choice;
switch (choice){
case 1: shops();
break;
case 2: cops();
break;
//case 3 / 4 ,5 ...2043 etc. split up into sub menus
}
}
void shops()
{
std::string name;
std::cout << "Enter the name you want to give him.\n";
std::cin.ignore(256, '\n');
std::getline (std::cin, name);
Shopowners ownerOne; ownerOne.setId (name);
datafunc();
}
void cops()
{
std::string name;
std::cout << "Enter the name you want to give him. \n";
std::cin.ignore(256, '\n');
std::getline (std::cin, name);
Policemen copperOne; copperOne.setId (name);
datafunc();
}
void randomEvents (People &personA)
{
std::cout << personA.attribute<<"\n\n"; //currently prog should end here with print out of attribute
}
void datafunc ()
{
std::string idtag;
std::cout<< "Type in the name on the sticker. \n";
std::getline (std::cin, idtag);
People* people = NULL;
if(idtag == Shopowners.getid()) {people = &Shopowners();} //skipping this ??????????
if(idtag == Policemen.getid()) {people = &Policemen();} //taking precedence!!!
randomEvents(*people);
}
int main()
{
move();
// other functions in gameloop
system ("pause");
return 0;
}
Ive put in vector.
It doesn't like the push_backs because I guess the input cin is a string which makes the whole thing awkward. because if a name is typed in as an idtag and vector wont accept that as a parameter then...???
I'm totally lost in datafunc, not sure I know at all what the hell I'm doing. I put a for loop in there but still get masses of error messages. Not sure if this is worth all the aggravation. In fact i've given up on the datafunc, I feel like I'm sticking a hammer into a clock mechanism.
#include <iostream>
#include "cstdio"
#include <cctype>
#include <ctime>
#include <string>
#include <vector>
class People {
public:
People():
attribute (0),
attributeB (0),
attributeC (0)
{}
int attribute;
int attributeB;
int attributeC;
void setId(std::string tag) { id = tag; }
std::string getid() {return id;}
protected:
std::string id;
};
class Shopowners : public People {
public:
Shopowners()
{
attribute = 25;
attributeB = 44;
id;
}
};
class Policemen : public People {
public:
Policemen()
{
attribute = 13;
attributeC = 55;
id;
}
};
std::vector<People*> people;
void selection();
void datafunc();
void shops();
void cops();
int renadomEvents();
void move()
{
char yesno = 'y';
std::cout << "If you want to move a car or person does it have a name-sticker on it? y/n \n";
std::cin>>yesno;
if (yesno=='y') {datafunc();}
else selection();
}
void selection()
{
int choice;
std::cout<<" Which toy do you want to move?\n";
std::cout<< " 1. A shopowner.\n";
std::cout<< " 2. A policeman.\n";
std::cout<< " 3. A car.\n";
std::cin>> choice;
switch (choice){
case 1: shops();
break;
case 2: cops();
break;
//case 3 / 4 ,5 ...2043 etc. split up into sub menus
}
}
void shops()
{
std::string name;
std::cout << "Enter the name you want to give him.\n";
std::cin.ignore(256, '\n');
std::getline (std::cin, name);
Shopowners ownerOne; ownerOne.setId (name);
people.push_back (name);
datafunc();
}
void cops()
{
std::string name;
std::cout << "Enter the name you want to give him. \n";
std::cin.ignore(256, '\n');
std::getline (std::cin, name);
Policemen copperOne; copperOne.setId (name);
people.push_back (name);
datafunc();
}
void randomEvents (People &personA)
{
std::cout << personA.attribute<<"\n\n"; //currently prog should end here with print out of attribute
}
void datafunc ()
{
std::string idtag;
std::cout<< "Type in the name on the sticker. \n";
std::getline (std::cin, idtag);
//People* people = NULL;
int i;
for (i=0; i<people.size();i++)
{idtag = idtag[i];}
if(idtag == Shopowners.getid()) {pers = &Shopowners();} //skipping this ??????????
if(idtag == Policemen.getid()) {pers = &Policemen();} //taking precedence!!!
randomEvents(pers);
}
int main()
{
move();
// other functions in gameloop
system ("pause");
return 0;
}
You are trying to push a std::string onto a People* vector. You need to push the person that has the string as its id.
Maybe try this:
1 2 3 4 5 6 7 8 9 10 11 12 13
void cops()
{
std::string name;
std::cout << "Enter the name you want to give him. \n";
std::cin.ignore(256, '\n');
std::getline (std::cin, name);
Policemen* copperOne = new Policeman; // create a pointer and allocate with new
copperOne->setId (name); // set his id
people.push_back (copperOne);
datafunc();
}