I'm a beginner and I want to use instance w of OlMainWindow in order to access _x by pressing address (OlMain->vref->_x=10;) through ui_MainWidow::setupUI() function, but when I compile this program then I get an error on line OlMain->vref->_x=10:
error: use of undefined type 'OlMainWindow'
Please help me fix this error.
ui_MainWidow.h
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <iostream>
#include "olvalue.h"
class OlValue;
class OlMainWindow;
class ui_MainWidow;
class ui_MainWidow {
public:
void setupUI(OlMainWindow* OlMain) {
OlMain->vref->_x=10; // _x = 10;
OlMain->vref->_x = 10;
std::cout << " ok";
}
};
#endif //UI_MAINWINDOW_H
olvalue.h
#include <iostream>
#ifndef VALUE_H
#define VALUE_H
#include "ui_mainwindow.h"
class OlValue;
class OlMainWindow;
class ui_MainWidow;
class OlValue
{
public:
int _x;
int _y;
public:
OlValue() {
_x = 10;
_y = 20;
}
};
#endif //VALUE_H
olmainwindow.h
#ifndef OLMAINWINDOW_H
#define OLMAINWINDOW_H
#include <iostream>
#include <string>
#include "olvalue.h"
class OlValue;
class OlMainWindow;
class ui_MainWidow;
class OlMainWindow
{
public:
OlValue* vref = new OlValue;
OlMainWindow();
~OlMainWindow();
void enterUsername();
private:
int val;
std::string _Username;
};
#endif //OLMAINWINDOW_H
olmainwidow.cpp
#include "olmainwindow.h"
#include <iostream>
#include <string>
class OlValue;
class OlMainWindow;
class ui_MainWidow;
OlMainWindow::OlMainWindow() {
ui_MainWidow* ui = new ui_MainWidow();
ui->setupUI(this);
}
OlMainWindow::~OlMainWindow() {
//delete ui;
}
void OlMainWindow::enterUsername() {
std::cout << "Please, enter Username: ";
std::getline(std::cin, _Username);
std::cout << "You'v accessed Username: " << _Username << std::endl;
}
main.cpp
#include "olmainwindow.h"
#include <iostream>
int main(int argc, char* argv[])
{
OlMainWindow* w = new OlMainWindow();
return 0;
}
In ui_MainWidow.h, the implementation of setupUI() is inlined, but when it tries to access the members of OlMainWindow it fails because the OlMainWindow class hasn't actually been defined yet, merely forward declared.
Your files are not setup correctly. You are creating dependencies where they don't belong, and then you are trying to use forward declarations to solve circular dependencies issues that shouldn't exist in the first place.
Try this instead:
OlValue.h
#ifndef OLVALUE_H
#define OLVALUE_H
class OlValue
{
public:
int _x = 10;
int _y = 20;
};
#endif //OLVALUE_H
ui_MainWindow.h
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
class OlMainWindow;
class ui_MainWindow {
public:
void setupUI(OlMainWindow* OlMain);
};
#endif //UI_MAINWINDOW_H
ui_MainWindow.cpp
#include "ui_MainWindow.h"
#include "OlMainWindow.h"
#include <iostream>
void ui_MainWindow::setupUI(OlMainWindow* OlMain) {
OlMain->vref->_x = 10;
OlMain->vref->_x = 10;
std::cout << " ok";
}
olMainWindow.h
#ifndef OLMAINWINDOW_H
#define OLMAINWINDOW_H
#include "OlValue.h"
#include <string>
class ui_MainWidow;
class OlMainWindow
{
public:
OlValue* vref = new OlValue;
OlMainWindow();
~OlMainWindow();
void enterUsername();
private:
ui_MainWidow* ui;
int val;
std::string _Username;
};
#endif //OLMAINWINDOW_H
olMainWindow.cpp
#include "olMainWindow.h"
#include <iostream>
#include <string>
OlMainWindow::OlMainWindow() {
ui = new ui_MainWindow();
ui->setupUI(this);
}
OlMainWindow::~OlMainWindow() {
delete ui;
}
void OlMainWindow::enterUsername() {
std::cout << "Please, enter Username: ";
std::getline(std::cin, _Username);
std::cout << "You'v accessed Username: " << _Username << std::endl;
}
main.cpp
#include "olMainWindow.h"
#include <iostream>
int main(int argc, char* argv[])
{
OlMainWindow w;
w.enterUsername();
return 0;
}
Related
For some reason I cannot use the "getNotify()" function attached to the "Broker" object. I added a comment to the line that is not working(in "Publisher" class). As an error I get "Error; pointer to incomplete class type is not allowed" Please help
the "Broker" class is implemented with Singleton-Pattern
Broker.h class:
#ifndef DEF_Broker
#define DEF_Broker
#include <iostream>
#include "classes.h"
using namespace std;
class Broker : Publisher
{
static Broker *instance;
Broker();
public:
static Broker* getInstance()
{
if(!instance)
{
instance = new Broker();
}
return instance;
}
void getNotify()
{
for(auto sub : SubscriberList)
{
if(t.msg == "Hello World")
{
SubCount++;
cout << SubCount << " - ";
sub->update(t.msg);
}
else if(t.msg == "Ping")
{
cout << "Ping" << endl;
sub->update("Pong");
}
}
}
};
Broker *Broker::instance = 0; // Null, because instance will be initialized on demand.
Broker::Broker(){}; // Private constructor so that no objects can be created.
#endif
classes.h :
#ifndef DEF_classes
#define DEF_classes
#include <iostream>
#include <list>
using namespace std;
class Broker;
class Subscriber
{
public:
void update(string msg)
{
cout << msg << endl;
}
};
class Topic
{
public:
string msg;
Topic(){};
Topic(string msg)
{
this->msg = msg;
}
};
class Publisher
{
protected:
list<Subscriber*> SubscriberList;
static int SubCount;
public:
Topic t;
Broker *broker;// = broker->getInstance();
Publisher(){}
Publisher(Topic t)
{
this->t = t;
};
void AddSub(Subscriber *sub)
{
SubscriberList.push_back(sub);
}
void notify(string msg)
{
broker->getNotify(); // this not working
}
};
int Publisher::SubCount = 0; // Initialize static member SubCount
#endif
Normally you would need to include broker.h in classes.h, however, this would create a circular dependency.
Therefore, implement the functions of Publisher in a .cpp file and include broker.h in that file. The forward declaration in classes.h (class broker;) needs to remain.
One possible way to solve this would be to create different files(headers and source files) for different classes. I have done this for you in this case so that you can take this example as a reference(starting point) for your future purposes/programs. Below are all the files:
Borker.h
#ifndef DEF_Broker
#define DEF_Broker
#include <iostream>
#include "Publisher.h"
class Broker : Publisher
{
static Broker *instance;
Broker();
public:
static Broker* getInstance()
{
if(!instance)
{
instance = new Broker();
}
return instance;
}
void getNotify();
};
#endif
Broker.cpp
#include "Broker.h"
#include "Subscriber.h"
Broker *Broker::instance = 0; // Null, because instance will be initialized on demand.
void Broker::getNotify()
{
for(auto sub : SubscriberList)
{
if(t.msg == "Hello World")
{
SubCount++;
std::cout << SubCount << " - ";
sub->update(t.msg);
}
else if(t.msg == "Ping")
{
std::cout << "Ping" << std::endl;
sub->update("Pong");
}
}
}
Broker::Broker()
{
}; // Private constructor so that no objects can be created.
Topic.h
#ifndef TOPIC_H
#define TOPIC_H
#include <iostream>
#include <list>
#include <string>
class Topic
{
public:
std::string msg;
Topic(){}
Topic(std::string msg);
};
#endif
Topic.cpp
#include "Topic.h"
Topic::Topic(std::string msg)
{
this->msg = msg;
}
Publisher.h
#ifndef PUBLISHER_H
#define PUBLISHER_H
#include <list>
#include "Topic.h"
class Broker;//needed for Borker *broker
class Subscriber;//needed for Subscriber*
class Publisher
{
protected:
std::list<Subscriber*> SubscriberList;
static int SubCount;
public:
Topic t;
Broker *broker;// = broker->getInstance();
Publisher(){}
Publisher(Topic t)
{
this->t = t;
};
void AddSub(Subscriber *sub);
void notify(std::string msg);
};
#endif
Publisher.cpp
#include "Publisher.h"
#include "Broker.h"//needed for broker->getNotify()
int Publisher::SubCount = 0; // Initialize static member SubCount
void Publisher::notify(std::string msg)
{
broker->getNotify(); // this not working
}
void Publisher::AddSub(Subscriber *sub)
{
SubscriberList.push_back(sub);
}
Subscriber.h
#ifndef SUBSCRIBER_H
#define SUBSCRIBER_H
#include <string>
class Subscriber
{
public:
void update(std::string msg);
};
#endif
Subscriber.cpp
#include "Subscriber.h"
#include <iostream>
void Subscriber::update(std::string msg)
{
std::cout << msg << std::endl;
}
The program compiles successfully as can be seen here.
#Ben #AnnopRana thanxs guys.
I got inspired from ur answers and i got the following solution
broker.h
#ifndef DEF_Broker
#define DEF_Broker
#include <iostream>
#include "classes.h"
using namespace std;
class Broker
{
static Broker *instance;
Broker();
public:
Publisher pub;
static Broker* getInstance()
{
if(!instance)
{
instance = new Broker();
}
return instance;
}
void getNotify()
{
for(auto sub : pub.SubscriberList)
{
if(pub.t.msg == "Hello World")
{
pub.SubCount++;
cout << pub.SubCount << " - ";
sub->Subscriber::update(pub.t.msg);
}
else if(pub.t.msg == "Ping")
{
cout << "Ping" << endl;
sub->Subscriber::update("Pong");
}
else
{
cout << "no such as topic" << endl;
}
}
}
};
Broker *Broker::instance = 0; // Null, because instance will be initialized on demand.
Broker::Broker(){}; // Private constructor so that no objects can be created.
#endif
classes.h
#ifndef DEF_classes
#define DEF_classes
#include <iostream>
#include <list>
using namespace std;
class Broker;
class Subscriber
{
public:
void update(string msg)
{
cout << msg << endl;
}
};
class Topic
{
public:
string msg;
Topic(){};
Topic(string msg)
{
this->msg = msg;
}
};
class Publisher
{
public:
list<Subscriber*> SubscriberList;
static int SubCount;
Topic t;
Publisher(){}
Publisher(Topic t)
{
this->t = t;
};
void AddSub(Subscriber *sub);
void notify(Broker *b);
};
#endif
publisher.cpp
#include "classes.h"
#include "Broker.h"//needed for broker->getNotify()
using namespace std;
int Publisher::SubCount = 0; // Initialize static member SubCount
void Publisher::notify(Broker *b)
{
b->getNotify();
}
void Publisher::AddSub(Subscriber *sub)
{
SubscriberList.push_back(sub);
}
Or is there a way to get ResponseState::EncoderTag out of class ResponseState?
The code is shown below
#include <iostream>
#include <memory>
#include <string>
using namespace std;
class MirroredMsgRespState
{
public:
virtual ~MirroredMsgRespState(){}
virtual uint32_t encoderTag() const = 0;
};
template<typename RespMsgT, uint32_t EncoderTag>
class ErrorAndEntryResponseState : public MirroredMsgRespState
{
public:
uint32_t encoderTag() const override
{
return EncoderTag;
}
};
using ResponseState = ErrorAndEntryResponseState<int, 48>;
int main()
{
unique_ptr<MirroredMsgRespState> myResp = make_unique<ResponseState>();
cout << myResp->encoderTag() << endl; // func 1
cout << ResponseState::encoderTag() << endl; // func 2
return 0;
}
The current implementation causes the second call to report an error
You could add a static method:
#include <iostream>
#include <memory>
#include <string>
using namespace std;
class MirroredMsgRespState
{
public:
virtual ~MirroredMsgRespState(){}
virtual uint32_t encoderTag() const = 0;
};
template<typename RespMsgT, uint32_t EncoderTag>
class ErrorAndEntryResponseState : public MirroredMsgRespState
{
public:
static uint32_t getEncoderTag()
{
return EncoderTag;
}
uint32_t encoderTag() const override
{
return getEncoderTag();
}
};
using ResponseState = ErrorAndEntryResponseState<int, 48>;
int main()
{
unique_ptr<MirroredMsgRespState> myResp = make_unique<ResponseState>();
cout << myResp->encoderTag() << endl; // func 1
cout << ResponseState::getEncoderTag() << endl; // func 2
return 0;
}
I'm trying to have a class in which the function changes the value of a private members of that class but I keep getting the error of "the use of an undeclared identifier." I thought if the function is a class member then they can access the private member?
My code for reference
Building.h
#ifndef BUILDING_H
#define BUILDING_H
#include "Point2D.h"
#include "GameObject.h"
class Building : public GameObject
{
private:
unsigned int pokemon_count;
Building();
Building(char,int, Point2D);
public:
void AddOnePokemon();
void RemoveOnePokemon();
void ShowStatus();
bool ShouldBeVisible();
};
#endif
Building.cpp
#include "Building.h"
#include "GameObject.h"
#include <iostream>
using namespace std;
Building::Building()
{
display_code = 'B';
location;
id_num = ' ';
state = '0';
pokemon_count = 0;
cout << "Building default constructed";
}
Building::Building(char in_code,int in_id, Point2D in_loc)
{
id_num = in_id;
location = in_loc;
display_code = in_code;
state = '0';
cout << "Building constructed";
}
void AddOnePokemon()
{
pokemon_count = pokemon_count+1;
}
void ReturnOnePokemon()
{
pokemon_count = pokemon_count-1;
}
void ShowStatus()
{
cout << "\"(" << pokemon_count << "pokemon is/are in this building";
}
Your functions are outside the scope of your class.
Add the class name in front of the functions and this should work:
void Building::AddOnePokemon()
This is my first "big" C++ project and I am stuck. I am trying to create a simple ASCII roguelike. I have a character class that is inherited by a Player class and a Monster class. The Monster class is inherited by Vampire and Werewolf classes.
In the startGame function of the GameSystem class I submit every element of a Monsters array (that is supposed to be filled with Vampire and Werewolf objects) to the function moveAround. Vampires, Werewolfs, and Monsters all have this function yet only the Monster moveAround function is being accessed. If you notice in the code below I have the virtual keyword provided in the Monster class.
This leads me to think I messed up when I filled the Monster array with the subclasses. I did this in the GameSystem constructor by randomly determining if a particular element of the Monster array was going to be a werewolf or a vampire.
I am using codeblocks and in terms of compiling I have g++ following C++11.
GameSystem.cpp
#include <iostream>
#include <string>
#include "GameSystem.h"
#include "Map.h"
#include "Player.h"
#include "Werewolf.h"
#include "Vampire.h"
#include "conio.h"
#include <cstdio>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <time.h>
GameSystem::GameSystem(string mapName){
srand (time(NULL));
_map.load(mapName);
_map.obtainSpawningLocations(_player.getToken(),_player);
Werewolf werewolf;
Vampire vampire;
for(int i = 0; i < 5; i++){
_spawnValue = rand() % 2; //We generate either 1 or 2
if(_spawnValue==1){
_theMonsters[i] = werewolf;
cout<<"Werewolf"<<endl;
}
else{
_theMonsters[i] = vampire;
cout<<"Vampire"<<endl;
}
_map.obtainSpawningLocations(_theMonsters[i].getToken(),_theMonsters[i]);
}
}
void GameSystem::startGame(){
bool isOver = false;
while(isOver!=true){
_map.print();
movePlayer();
for(int i = 0; i <5; i++){
_theMonsters[i].moveAround(); //prints out Monster.moveAround()
//I need it to print out Vampire.moveAround() and //Werewolf.moveAround
}
}
}
void GameSystem::movePlayer(){
char input;
input = getch();
string clearScreenString(100,'\n'); //Prints out a newLine char 100 times
cout << clearScreenString;
_map.checkMovement(input, _player);
}
char GameSystem::getch(){
char buf=0;
struct termios old={0};
fflush(stdout);
if(tcgetattr(0, &old)<0)
{perror("tcsetattr()");}
old.c_lflag&=~ICANON;
old.c_lflag&=~ECHO;
old.c_cc[VMIN]=1;
old.c_cc[VTIME]=0;
if(tcsetattr(0, TCSANOW, &old)<0)
{perror("tcsetattr ICANON");}
if(read(0,&buf,1)<0)
{perror("read()");}
old.c_lflag|=ICANON;
old.c_lflag|=ECHO;
if(tcsetattr(0, TCSADRAIN, &old)<0)
{perror ("tcsetattr ~ICANON");}
//printf("%c\n",buf);
return buf;
}
GameSystem.h
#pragma once
#include "Map.h"
#include <string>
#include <list>
using namespace std;
class GameSystem
{
public:
GameSystem(string mapName); //Constructor
void startGame(); //Start the game
char getch();
void movePlayer();
private:
//int _numberOfMonsters = 5; //We'll make this a random number later
Map _map;
Player _player;
Monster _monster;
Monster _theMonsters[5];
int _x;
int _y;
int _spawnValue;
};
Character.cpp
#include <string>
#include "Character.h"
using namespace std;
Character::Character(){
}
char Character::getToken(){
return _token;
}
void Character::setLocation(int x, int y){
_x = x;
_y = y;
}
void Character::getLocation(int &x, int &y){
x = _x;
y = _y;
}
Character.h
#pragma once
#include <string>
class Character{
public:
Character();
char getToken();
void setLocation(int x, int y);
void getLocation(int &x, int &y);
protected:
int _x;
int _y;
char _token = '!';
};
Map.cpp
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <cstring>
#include <random>
#include <ctime>
#include <tuple>
#include "Map.h"
#include <time.h>
Map::Map(){
srand (time(NULL));
}
void Map::load(string levelName){
ifstream theStream;
theStream.open(levelName);
if(theStream.fail()){
perror(levelName.c_str());
system("PAUSE");
exit(1);
}
string line;
while(getline(theStream, line)){
_mapData.push_back(line);
}
theStream.close();
}
void Map::obtainSpawningLocations(char characterToken,Character &_character){
/*
Below code provides all the possible spawning locations for the player
and stores them in an array of tuples.
*/
tuple<int,int> myTuple[600]; //Hard coded 600 value is messy. Change later
int numberOfSpawnPoints = 0;
int upperLimitForNumberGenerator = 0;
/*
The for loop below records all of the possible spawning locations and stores them in the tuple array
*/
for(int i = 0; i<_mapData.size();i++){
for(int j = 0; j<_mapData[i].size();j++){
if(_mapData[i][j]=='.'){
get<0>(myTuple[numberOfSpawnPoints]) = j;
get<1>(myTuple[numberOfSpawnPoints]) = i;
numberOfSpawnPoints++;
}
}
}
upperLimitForNumberGenerator = numberOfSpawnPoints;
int characterCoordinates = rand()%upperLimitForNumberGenerator;
int xCoordinate = get<0>(myTuple[characterCoordinates]);
int yCoordinate = get<1>(myTuple[characterCoordinates]);
_mapData[yCoordinate][xCoordinate] = characterToken; //Remember y is first and x is second
_character.setLocation(xCoordinate, yCoordinate);
}
void Map::print(){
for(int i=0;i<_mapData.size(); i++){
printf("%s\n", _mapData[i].c_str());
}
printf("\n");
}
void Map::checkMovement(char input, Player &aPlayer){
int x;
int y;
aPlayer.getLocation(x,y);
char aLocation;
switch(input) {
case 'w':
case 'W': //If 1 up from the player token is a '.' then we move him up
//via a different function
//Otherwise we do nothing.
aLocation = returnLocation(x,y-1);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y-1][x] = '#';
aPlayer.setLocation(x,y-1);
}
else
cout<<"Can't go here!"<<endl;
break;
case 'a':
case 'A':
aLocation = returnLocation(x-1,y);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y][x-1] = '#';
aPlayer.setLocation(x-1,y);
}
else
cout<<"Can't go here!"<<endl;
break;
case 's':
case 'S':
aLocation = returnLocation(x,y+1);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y+1][x] = '#';
aPlayer.setLocation(x,y+1);
}
else
cout<<"Can't go here!"<<endl;
break;
case 'd':
case 'D':
aLocation = returnLocation(x+1,y);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y][x+1] = '#';
aPlayer.setLocation(x+1,y);
}
else
cout<<"Can't go here!"<<endl;
break;
default:
cout<<"Invalid input";
system("PAUSE");
break;
}
}
char Map::returnLocation(int x, int y){
cout<<x<<endl;
cout<<y<<endl;
char aSpot = _mapData[y][x];
return aSpot;
}
Map.h
#pragma once
#include <vector>
#include <fstream>
#include <string>
#include <tuple>
#include <ctime>
#include <random>
#include "Player.h"
#include "Monster.h"
using namespace std;
class Map
{
public:
Map(); //Constructor
void load(string levelName);
void obtainSpawningLocations(char characterToken, Character &aCharacter);
void checkMovementMonsters(char input, Monster &aMonster);
//void obtainSpawningLocationsForMonsters(char characterToken, Monster aMonster);
void print();
void checkMovement(char input, Player &aPlayer);
void movement(char characterToken);
char returnLocation(int x,int y);
// int numberOfSpawnPoints;
private:
vector <string> _mapData;
Player _player;
Monster _monster;
};
Monster.cpp
#include <iostream>
#include <string>
#include "Monster.h"
using namespace std;
Monster::Monster(){
}
void Monster::moveAround(){
cout<<"Monster Mash"<<endl;
}
Monster.h
#pragma once
#include <string>
#include "Character.h"
class Monster: public Character{
public:
Monster();
virtual void moveAround();
protected:
char _token = 'M';
int _x;
int _y;
};
Werewolf.cpp
#include <iostream>
#include <string>
#include "Werewolf.h"
using namespace std;
Werewolf::Werewolf(){
}
void Werewolf::moveAround(){
cout<<"Werewolf moving around"<<endl;
}
Werewolf.h
#pragma once
#include <string>
#include "Character.h" //For inheritance/polymorphism
#include "Monster.h"
class Werewolf: public Monster{
public:
Werewolf();
void moveAround();
private:
char _token = 'W';
};
Vampire.cpp
#include <iostream>
#include <string>
#include "Vampire.h"
using namespace std;
Vampire::Vampire(){
}
void Vampire::moveAround(){
cout<<"Vampire moving around"<<endl;
}
Vampire.h
#pragma once
#include <string>
#include "Character.h" //For inheritance/polymorphism
#include "Monster.h"
class Vampire: public Monster{
public:
Vampire();
virtual void moveAround();
private:
char _token = 'V';
};
Player.cpp
Player::Player(){
}
Player.h
#pragma once
#include <string>
#include "Character.h"
using namespace std;
class Player : public Character {
public:
Player();
protected:
int _x;
int _y;
char _token = '#';
};
Main
#include <iostream>
#include "GameSystem.h"
using namespace std;
int main()
{
GameSystem gameSystem("LevelOne.txt");
gameSystem.startGame();
return 0;
}
The level text file:
############################################
#..........................................#
#..........................................#
#...........................^..............#
#..........................................#
#......................#...................#
#......................#...................#
#......................#...................#
#............^.........#...................#
#......######..........#..&................#
#......\...............#...................#
#......................#...................#
#..........................................#
#..........................................#
############################################
There is no virtual dispatch happening on _theMonsters[i].moveAround(). You need to have an array of pointers to objects of type monster. In fact, there are quite some problems in the way you try to set up the class hierarchy, like, having identically named member variables in derived classes.
There are a couple of issues here.
Monster::_token, Werewolf::_token, and Vampire::_token are all different variables. A Werewolf object has both Monster::_token and Werewolf::_token.
Monster _theMonsters[5] is an array of 5 Monster objects. It will never be a Vampire or a Werewolf, always a Monster. There is no virtual dispatch to be done since the objects will always be the same type: Monster.
Virtual dispatch only applies to pointers and references. To make this work, you'll need to use an array of pointers to Monsters: Monster* _theMonsters[5]. Then you can fill it like _theMonsters[i] = new Vampire(). If you do this, you'll need to remember to delete the objects when you're done with them, or you could use a smart pointer like std::unique_ptr or std::shared_ptr instead of raw Monster*s.
Im on year 10 and our teacher wants us to create an original project and using pointers
What I want to do is to create Members and be able to sort the members by there names and print them
When I run my code it says Invalid Access
Team.h
#ifndef TEAM_H
#define TEAM_H
#include "Staff.h"
#include <vector>
#include <iostream>
using std::vector;
class Team: public Staff
{
public:
Team();
~Team();
vector<Staff *> &getVector();
private:
vector<Staff *> myStaffs;
};
#endif // TEAM_H
Team.cpp
Team::Team()
{
for(unsigned int iStaff = 0; iStaff < myStaffs.size(); iStaff++)
{
myStaffs[iStaff] = createStaff(iStaff);
}
}
vector<Staff*>& Team::getVector()
{
return myStaffs;
}
Command class will do the sorting of team and print all team members
Command.cpp
void Command::printStaffs(vector<Staff*>&myStaffs)
{
for(unsigned int iStaff = 0; iStaff < myStaffs.size(); iStaff++)
{
std::cout << "Staff ID number: "<< myStaffs[iStaff]->getStaId() << std::endl
<< "Staff Skills 1: " << *myStaffs[iStaff]->getStaSkill() << std::endl
<< "Staff Skills 2: " << *myStaffs[iStaff]->getStaSkill() << std::endl
<< "Staff Skills 3: " << *myStaffs[iStaff]->getStaSkill() << std::endl
<< std::endl;
}
}
Command.h
#ifndef CommandH
#define CommandH
#include "Team.h"
#include <vector>
#include <iostream>
using std::vector;
class Command: public Team
{
public:
Command(){}
~Command(){}
void sortVector(vector<Staff* >&vectorTemp);
void printStaffs(vector<Staff* >&);
private:
vector<Staff *> vectEmployee;
};
//--------------------------------------------------------------------------
#endif
main.cpp
#include <iostream>
#include <conio.h>
#include "Team.h"
#include "Command.h"
int main()
{
Team t;
Command c;
c.printStaffs(t.getVector());
getch();
return 0;
}
Staff.h
#ifndef STAFF_H
#define STAFF_H
#include <cstdlib>
#include <ctime>
#include <string>
using std::rand;
class Staff
{
public:
Staff();
~Staff();
static Staff* createStaff(int); // creates staffs
int** getStaSkill();
int getStaId(); // returns Staff ID
static int genRanNum(int); //Generate random number
private:
int *staSkill[3];
int staId;
//int staDeptAsigned;
};
#endif
Staff.cpp
#include "Staff.h"
Staff::Staff()
{
*staSkill = new int[3];
}
Staff *Staff::createStaff(int s)
{
Staff *staff = new Staff();
staff->staId = s;
*(staff->staSkill[0]) = genRanNum(10);
*(staff->staSkill[1]) = genRanNum(10);
*(staff->staSkill[2]) = genRanNum(10);
return staff;
}
int** Staff::getStaSkill()
{
return staSkill;
}
int Staff::getStaId()
{
return staId;
}
int Staff::genRanNum(int num)
{
return 1 +(std::rand()%num);
}
Staff::~Staff(){}
When you construct a Team, you have the following constructor:
Team::Team()
{
for(unsigned int iStaff = 0; iStaff < myStaffs.size(); iStaff++)
{
myStaffs[iStaff] = createStaff(iStaff);
}
}
However, myStaffs is a member of Team and gets default constructed as empty, so nothing happens here since myStaffs.size() == 0.
Calling printStaffs on this Team::getVector() will correctly inform you that the vector is empty:
int main()
{
Command c;
Team t; // t.myStaffs will be empty
c.printStaffs(t.getVector()); // passes an empty vector to printStaffs
return 0;
}
You might want to pass a number to your Team constructor to create that many staffs:
Team::Team(int number_of_staff)
{
for(unsigned int iStaff = 0; iStaff < number_of_staff; iStaff++)
{
myStaffs.push_back(createStaff(iStaff));
}
}
int main()
{
Command c;
Team t(5); // t.myStaffs will contain 5 staff members
c.printStaffs(t.getVector()); // passes vector of 5 staff
return 0;
}