Superclass member pointer becomes null when accessed by subclass - c++

I've been recently doing a lot of reading and decided to try and implement a simple State pattern to try and see how things fit together.
However, I've ran into an issue I've never come across before: The Scene's subclass (Start) doesn't seem to inherit the value of a pointer set by the superclass' constructor.
Here's the code
//main.cpp
#include "Game/game.hpp"
#include "Game/Scene/start.hpp"
int main()
{
Game::Game *g = new Game::Game;
Game::Scene::Start *s = new Game::Scene::Start(g);
g->set_scene(s);
g->loop();
delete g;
return 0;
}
//Game/Scene/Scene.hpp
#ifndef GAME_SCENE_H
#define GAME_SCENE_H
namespace Game
{
class Game;
namespace Scene
{
class Scene
{
public:
Scene(Game *game);
virtual ~Scene();
virtual void handle_input() = 0;
virtual void update();
protected:
Game *game;
};
}
}
#endif
//Game/Scene/Scene.cpp
#include "scene.hpp"
#include <iostream>
Game::Scene::Scene::Scene(Game *game): game(game)
{
std::cout << "Game::Scene::Scene::Scene() > game: " << this->game << std::endl;
}
Game::Scene::Scene::~Scene() {}
void Game::Scene::Scene::update()
{
std::cout << "Game::Scene::Scene::update(): game: " << game << std::endl;
}
//Game/Scene/start.hpp
#ifndef GAME_SCENE_START_H
#define GAME_SCENE_START_H
#include "scene.hpp"
namespace Game
{
namespace Scene
{
class Start:
public Scene
{
public:
Start(Game *game);
void handle_input() override;
void update() override;
protected:
Game *game;
};
}
}
#endif
//Game/Scene/start.cpp
#include "start.hpp"
#include "../game.hpp"
#include <iostream>
Game::Scene::Start::Start(Game *game): Scene(game) {
std::cout << "Game::Scene::Start::Start() > game: " << this->game << std::endl;
}
void Game::Scene::Start::handle_input()
{}
void Game::Scene::Start::update()
{
Scene::update();
std::cout << "Game::Scene::Start::update(): game: " << game << std::endl;
game->set_keep_going(false);
}
//Game/game.hpp
#ifndef GAME_H
#define GAME_H
#include "Scene/scene.hpp"
namespace Game
{
class Game
{
public:
Game();
void loop();
void set_keep_going(bool state);
void set_scene(Scene::Scene *scene);
private:
bool keep_going;
Scene::Scene *current_scene;
};
}
#endif
//Game/game.cpp
#include "game.hpp"
#include <iostream>
Game::Game::Game():
keep_going(true),
current_scene(nullptr)
{}
void Game::Game::loop()
{
while(keep_going && current_scene)
{
current_scene->handle_input();
current_scene->update();
}
return;
}
void Game::Game::set_keep_going(bool state)
{
keep_going = state;
}
void Game::Game::set_scene(Scene::Scene *scene)
{
if(scene)
{
if(current_scene)
{
delete current_scene;
}
current_scene = scene;
}
}
And here is the output it generates:
Game::Scene::Scene::Scene() > game: 00000210FA38B330
Game::Scene::Start::Start() > game: 0000000000000000
Game::Scene::Scene::update(): game: 00000210FA38B330
Game::Scene::Start::update(): game: 0000000000000000
Segmentation fault
If I remove the 'this->' part that I used in the subclass constructor for debugging the output becomes this
Game::Scene::Scene::Scene() > game: 000001D247B5B370
Game::Scene::Start::Start() > game: 000001D247B5B370
Game::Scene::Scene::update(): game: 000001D247B5B370
Game::Scene::Start::update(): game: 0000000000000000
Segmentation fault
Which just makes it even weirder to me that it suddenly decided to reset itself.
It's without a doubt an incredibly simple thing that I'm overlooking, or some pointer shennanigans I've never run into before, but I'm stumped on what can possibly be going on here.
Any help or feedback om my code would be appriciated.

You have two members variables Scene::game and Start::game. You never set Start::game. By default, game resolves to Scene::game and the base class's variable is shadowed. Turn on compiler warnings, maybe the compiler will warn about it, not sure in this particular case.
Fix:
Game::Scene::Start::Start(Game *game): Scene(game), game(game)
{
std::cout << "Game::Scene::Start::Start() > game: " << this->game << std::endl;
}
Or just delete Start::game and use the member from Scene. This probably what you have meant in the first place hence the protected qualifier.
If you want feedback - do not use new, use std::unique_ptr instead. Even better, do not use ptrs at all this is not Java.

Related

Accessing a function of a objects class as an array of pointers of another class

y'all I'm having an issue trying to access the member functions of an object that I have stored in an array of pointers full of objects.
Header:
#ifndef COURSEGRADES__H
#define COURSEGRADES__H
#include "Essay.h"
#include "FinalExam.h"
#include "PassFailExam.h"
#include "GradedActivity.h"
class CourseGrades:public Essay, public FinalExam, public PassFailExam, public GradedActivity
{
public:
CourseGrades();
void setLab(GradedActivity &l);
void setPassFailExam(PassFailExam &pf);
void setEssay(Essay &e);
void setPassFailFinal(FinalExam &fe);
void print();
private:
GradedActivity *grades[4];
};
#endif // COURSEGRADES_H
CPP
#include "CourseGrades.h"
#include <iostream>
CourseGrades::CourseGrades()
{
//ctor
}
void CourseGrades::setLab(GradedActivity &l)
{
grades[0] = &l;
}
void CourseGrades::setPassFailExam(PassFailExam &pf)
{
grades[1] = &pf;
}
void CourseGrades::setEssay(Essay &e)
{
grades[2] = &e;
}
void CourseGrades::setPassFailFinal(FinalExam &fe)
{
grades[3] = &fe;
}
void CourseGrades::print()
{
std::cout << grades[0]->getScore() << "\t" << grades[0]->getLetterGrade() << std::endl;
std::cout << grades[1]->getScore() << "\t" << grades[1]->getLetterGrade() << std::endl;
std::cout << grades[2]->getScore //this function exists in the Essay class but I can't access it from here.
}
So I'm trying to access the third object in the grade array which is an object of the essay class which includes a unique function that is separate from the get score function in the GradeActivity class. I'll also need to access its unique getLetterGrade method but once I get one I should be able to find out how to get the other. Any help would be greatly appreciated.

In c++, How can I share data between two classes efficiently?

#include "dataConsumer.h"
#include <iostream>
#include <Windows.h>
DataConsumer::DataConsumer(){}
DataConsumer::~DataConsumer(){}
void DataConsumer::Body()
{
std::cout << "DataConsumer Start" << std::endl;
while (1)
{
//I want to get providerData_ of DataProvide class in here
Sleep(1000);
}
}
#include "dataProvider.h"
#include <iostream>
#include <Windows.h>
DataProvider::DataProvider(){}
DataProvider::~DataProvider(){}
void DataProvider::Body()
{
std::cout << "DataProvider Start" << std::endl;
while (1)
{
//Update data in here
providerData_++;
Sleep(1000);
}
}
There are two classes.
And I want to get providerData_ of dataProvider class in dataConsumer class.
To resolve this situation, I thought the following is one solution.
I made singleton dataTransfer class like below.
But I am not sure whether this is a general solution in c++.
First of all, I want to know whether my solution is available.
To the next, If you know the better solution(or design pattern) to resolve my situation, please advise to me.
#ifndef DATATRANSFER_H
#define DATATRANSFER_H
class DataTransfer
{
public:
static DataTransfer* getInstance()
{
static DataTransfer instance;
return &instance;
}
void GetData(unsigned int *data)
{
if(data)
*data = data_;
}
void SetData(unsigned int *data)
{
if(data)
data_ = *data;
}
private:
DataTransfer(){}
~DataTransfer(){}
unsigned int data_;
};
#endif
#include "dataConsumer.h"
#include "dataTransfer.h"
#include
#include
DataConsumer::DataConsumer(){}
DataConsumer::~DataConsumer(){}
void DataConsumer::Body()
{
unsigned int data = 0;
std::cout << "DataConsumer Start" << std::endl;
while (1)
{
//I want to get providerData_ of DataProvide class in here
DataTransfer::getInstance()->GetData(&data);
std::cout << "DataConsumer data:" << data << std::endl;
Sleep(1000);
}
}
#include "dataProvider.h"
#include "dataTransfer.h"
#include
#include
DataProvider::DataProvider() : providerData_(0)
{
}
DataProvider::~DataProvider(){}
void DataProvider::Body()
{
std::cout << "DataProvider Start" << std::endl;
while (1)
{
//Update data in here
providerData_++;
DataTransfer::getInstance()->SetData(&providerData_);
Sleep(1000);
}
}
If both classes need to be able to get and set the providerData_, I would create a third Data class to own the providerData_.
Then I could give a pointer of the Data class to all the classes that needed access to that data.
There are 3 patterns called aggregation, composition and association in software architecture.
The pattern in which class Foo can use class Bar but does not "own" it and both classes remain independent is Association.
DataConsumer have a pointer to DataProvider :
// Association
class DataConsumer{
private:
DataProvider* provider;
public:
void setProvider(DataProvider* p) { provider = p; }
void Body();
int /* or whatever data type */ getData()
{
if(provider != nullptr)
{
return provider->getData();
}
else
{
// handle provider not being set
return ...;
}
}
};
DataProvider must be allocated / created outside of DataConsumer and is independent.
Read this answer and this answer for a better explanation on these pattern.

Trying to access variables from another class

Im having an issue getting my variable from my original class to print in another class method
Quick example of my issue:
say the variable was declared here in the test.h file:
class player{
private:
int x = 10;
void setX(); //method for setting X from user input
int getX(); //Method for retrieving variable
}
Then in another class method where i want to print X
class inTheWoods{
public:
printInfo();
}
test.cpp file:
void player::setX(){
cout << "Set X to a number:" << endl;
cin >> x
}
int player::getX(){
return x;
}
int inTheWoods::printInfo(){
player playerObj; //Player object to access methods in player class
cout << playerObj.getX();
}
main.cpp:
int main(){
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
Whenever I run my program that resembles this problem the int does not display correctly and throws me a strange negative number. I hope this isnt too much code and that I documented everything correctly
If you want the classes to be in a separate files, it should still work:
Main.cpp
#include <iostream>
#include "inTheWoods.h"
int main()
{
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
Player.h
#pragma once
#include <iostream>
class Player
{
int x = 10;
void setX();
public:
int getX();
};
Player.cpp
#include "Player.h"
void Player::setX()
{
std::cout << "Set X to a number:" << std::endl;
std::cin >> x;
}
int Player::getX()
{
return x;
}
inTheWoods.h
//#pragma once
#include "Player.h"
#include <iostream>
class inTheWoods
{
public:
void printInfo();
};
inTheWoods.cpp
#include "inTheWoods.h"
void inTheWoods::printInfo()
{
Player playerObj; //Player object to access methods in player class
std::cout << playerObj.getX();
}
#pragma once is a preprocessor that prevents multiple includes, in case you didn't know. You can choose to skip it (Visual Studio auto-generated the file with the line).
In summary, these are the changes I needed to make from your implementation:
Move declaration of getX() from private to public.
Add semicolons to the end of every class.
Add a return type to printInfo(). If you don't want a function to return anything, the return type is void. Unless you care declaring a constructor, which doesn't seem to be the case here.
Here is the working one. It's always a good practice to give a constructor, in order to create an instance with some default values. the following code will work hopefully according to your requirements:
main.cpp
#include <iostream>
#include "inTheWoods.h"
int main()
{
inTheWoods woodsObj;
woodsObj.printInfo();
return 0;
}
player.h
#pragma once
class player
{
private:
int m_x;
public:
player();
player(const int& x);
void setX(); //method for setting X from user input
const int& getX()const; //Method for retrieving variable
};
player.cpp
#include "player.h"
#include <iostream>
player::player() // defualt constructor
:m_x(0) {}
player::player(const int& x)
:m_x(x) {} // parameterised
void player::setX()
{
std::cout << "Set X to a number:" << std::endl;
std::cin >> m_x;
}
const int& player::getX()const
{
return m_x;
}
inTheWoods.h
#pragma once
class inTheWoods
{
public:
inTheWoods();
~inTheWoods();
void printInfo();
};
inTheWoods.cpp
#include "inTheWoods.h"
#include "player.h"
#include <iostream>
inTheWoods::inTheWoods() {}
inTheWoods::~inTheWoods() {}
void inTheWoods::printInfo()
{
//Player object to access methods in player class
player playerObj; // will beinitialized with 0
player playerObj2(10); // will beinitialized with 10
std::cout << playerObj.getX() <<std::endl;
std::cout << playerObj2.getX() <<std::endl;
}
Edit: Well if you wanna allow the user to set values your printInfo() must be as follows:
void inTheWoods::printInfo()
{
//Player object to access methods in player class
player playerObj; // will beinitialized with 0
playerObj.setX();
std::cout << playerObj.getX() <<std::endl;
}

c++ getter not returning changed value outside class

I have 1 main class
class Vehicle{
private:
int fuel;
public:
int get_fuel(){ return this->fuel; }
void set_fuel(int fuel){ this->fuel = fuel; }
};
also 1 subclass of Vehicle
class Car : public Vehicle{
public:
Car();
};
Car::Car(){
set_fuel(500);
}
also my main.cpp file
#include <cstdlib>
#include <iostream>
#include "Vehicle.h"
#include "Car.h"
using namespace std;
int main(int argc, char *argcv[]){
Car c;
cout << c.get_fuel() << endl; //500
//set fuel to 200
c.set_fuel(200);
//print fuel again
cout << c.get_fuel() << endl;//still 500
}
why after using the setter the value still remains the same after i use the getter?
On VC++ 2012 your exact code works as expected. Output is 500 and 200.
class Vehicle {
private:
int _fuel;
public:
Vehicle(){
_fuel = 0;
}
int get_fuel(){
return _fuel;
}
// I like chainable setters, unless they need to signal errors :)
Vehicle& set_fuel(int fuel){
_fuel = fuel;
return *this;
}
};
class Car : public Vehicle {
public:
Car():Vehicle(){
set_fuel(500);
}
};
// using the code, in your main()
Car car;
std::cout << car.get_fuel() << std::endl; // 500
car.set_fuel(200);
std::cout << car.get_fuel() << std::endl; // actually 200
This is a slightly modified version. Place it in your .CPP file and try it. It can't not work!
PS: Stop using properties that have the same name as arguments. Always having to use this-> is very not cool! When you'll forget to use the this->, you'll see the bug of the century when you'll assign the value to itself and can't figure out what goes wrong.

Static Data Members

Please have a look at the following code
GameObject.h
#pragma once
class GameObject
{
public:
GameObject(int);
~GameObject(void);
int id;
private:
GameObject(void);
};
GameObject.cpp
#include "GameObject.h"
#include <iostream>
using namespace std;
static int counter = 0;
GameObject::GameObject(void)
{
}
GameObject::GameObject(int i)
{
counter++;
id = i;
}
GameObject::~GameObject(void)
{
}
Main.cpp
#include <iostream>
#include "GameObject.h"
using namespace std;
int main()
{
//GameObject obj1;
//cout << obj1.id << endl;
GameObject obj2(45);
cout << obj2.id << endl;;
// cout << obj2.counter << endl;
GameObject obj3(45);
GameObject obj4(45);
GameObject obj5(45);
//Cannot get Static value here
//cout << "Number of Objects: " << GameObject
//
system("pause");
return 0;
}
Here, I am trying to record how many instances have been created. I know it can be done by a static data member, but I can't access it withing the Main method! Please help!
PS:
I am seeeking for a direct access, without a getter method
Your static variable, counter cannot be accessed because it isn't a member of GameObject. If you want to access the counter, you'll need to do something like this:
GameObject.h
#pragma once
class GameObject
{
public:
...
static int GetCounter();
...
};
GameObject.cpp
int GameObject::GetCounter()
{
return counter;
}
Then you can access the variable like:
cout << "Number of Objects: " << GameObject::GetCounter();
Of course, there are other ways of accessing a static variable, such as making the counter variable a static member of your GameObject class (which I would recommend).
In your code, counter is not a static member of your class, but just a good old global variable. You can read up on how to declare static member variables anywhere on the net, but here are some snippets:
GameObject.h
#pragma once
class GameObject
{
public:
GameObject(void);
GameObject(int);
~GameObject(void);
private:
int id;
// static members
public:
static int counter; // <<<<<<<<<<< declaration
};
ameObject.cpp
#include "GameObject.h"
int GameObject::counter = 0; // <<<<<<<<<<< instantiation
GameObject::GameObject(void)
{
counter++;
}
GameObject::GameObject(int i)
{
counter++;
id = i;
}
GameObject::~GameObject(void)
{
}
Main.cpp
#include <iostream>
#include "GameObject.h"
using namespace std;
int main()
{
GameObject obj2(45);
cout << "version one: " << obj2.counter << endl;
// second version:
cout << "version two: " << GameObject::counter << endl;
system("pause");
return 0;
}
Afaik accessing static members on an instance of that class should work fine, but it gives the wrong impression, you should prefer version two.
Never mind, I did it with a getter method. Closing thread