class ZombieLand : public Singleton<ZombieLand>
{
DECLARE_SINGLETON(ZombieLand);
public:
MachineState* world[19][19];
bool map[19][19];
MachineState* getField(int x, int y)
{
return world[x][y];
}
void setWorld(MachineState state)
{
world[state.x][state.y] = &state;
map[state.x][state.y] = true;
}
};
struct MachineState
{
template <typename MachineTraits>
friend class Machine;
enum Facing { UP, RIGHT, DOWN, LEFT};
MachineState()
: m_ProgramCounter(1)
, m_ActionsTaken(0)
, m_Facing(UP)
, m_Test(false)
, m_Memory(nullptr)
,x(0)
,y(0)
,point1(25, 10)
,point2(10, 40)
,point3(40, 40)
{ }
int m_ProgramCounter;
int m_ActionsTaken;
Facing m_Facing;
bool m_Test;
bool m_occupied;
int x;
int y;
Point point1;
Point point2;
Point point3;
int GetActionsPerTurn() const throw() { return m_ActionsPerTurn; }
int GetMaxMemory() const throw() {return m_MaxMemory; }
bool GetTruth() const throw() { return m_InfectOnAttack; }
void setPoint(Point p1, Point p2, Point p3)
{
point1=p1;
point2=p2;
point3=p3;
}
};
I later call the getField function by doing
MachineState *Field1 = ZombieLand::get().getField(state.x, state.y-1 );
The problem is that when i try to access a member by doing Field1->getTruth() it's returning me the address of the pointer rather than the actual value(false or true). I don't understand why this is happening
template <class T>
class Singleton
{
private:
static T* _instance;
protected:
Singleton() {}
public:
static T& get()
{
if (_instance)
{
return *_instance;
}
else
{
_instance = new T();
return *_instance;
}
}
};
if(ZombieLand::get().map[state.x+2][state.y] == true)
{
MachineState *field3 = ZombieLand::get().getField(state.x+2, state.y);
std::cout<<"FOUND FIELD"<<Field3->getTruth();
}
when this if statement becomes true it prints "FOUND FIELD 0246" onto my console
As we do not have the signature of both get and getField it is difficult to tell.
But perhaps try
*(ZombieLand::get().getField(state.x, state.y-1 ))
To get the value that the pointer is pointing to.
EDIT
It helps to read the code i.e.
MachineState * world [19][19];
is a 2D array of pointers. Nowhere in this code is those pointers given a value so as it stands you are just lucky that the thing does not just die.
Therefore,
MachineState *getField(int x, int y)
{
return world[x][y];
}
As specified by the signature of the function as well!
But where in this code do you give the pointer a value or meaning?
OK, now I think you've finally posted the code that has the problem
class ZombieLand : public Singleton<ZombieLand>
{
DECLARE_SINGLETON(ZombieLand);
public:
MachineState* world[19][19];
bool map[19][19];
MachineState* getField(int x, int y)
{
return world[x][y];
}
void setWorld(MachineState state)
{
world[state.x][state.y] = &state;
map[state.x][state.y] = true;
}
};
This is undefined behaviour because you are saving the pointer to a local variable state. The state variable gets destroyed after you have exited the setWorld function, so your world array is just holding pointers to destroyed objects, That's why you have garbage values.
Rewrite this class without pointers.
class ZombieLand : public Singleton<ZombieLand>
{
DECLARE_SINGLETON(ZombieLand);
public:
MachineState world[19][19];
bool map[19][19];
MachineState* getField(int x, int y)
{
return &world[x][y];
}
void setWorld(const MachineState& state)
{
world[state.x][state.y] = state;
map[state.x][state.y] = true;
}
};
Pointers are almost always a bad idea, you should try to write code without them.
Got there in the end at least.
void setWorld(MachineState state)
{
world[state.x][state.y] = &state;
map[state.x][state.y] = true;
}
You are initializing the contents of the world array with the memory address of a local variable on the stack that goes out of scope and is no longer valid after setWorld() exits, leaving the array pointing at invalid MachineState objects. When getField() is called later on, you get random data from the current call stack.
If you want the array to point to external MachineState instances, you need to pass them in by reference instead of by value so you get the address of the original object and not a temporary anymore:
void setWorld(MachineState &state)
{
world[state.x][state.y] = &state;
map[state.x][state.y] = true;
}
Otherwise, change the array to not hold pointers anymore:
class ZombieLand : public Singleton<ZombieLand>
{
DECLARE_SINGLETON(ZombieLand);
public:
MachineState world[19][19];
bool map[19][19];
MachineState* getField(int x, int y)
{
return &world[x][y];
}
void setWorld(const MachineState &state)
{
world[state.x][state.y] = state;
map[state.x][state.y] = true;
}
};
Related
Below is a simple strategy pattern implemented using the base class references to a derived object. The solution does not produce an expected result (12 and 2). When base class reference is switched to pointers, it works. Can someone explain what is happening behind the scenes with references here? The issue is in the setStrategy() method of the Context class. I am wondering why doesn't the strategy variable reference the ConcreteStrategy2 after the call to setStrategy() method?
#include <iostream>
class Strategy {
public:
virtual ~Strategy() = default;
virtual int execute(int x, int y) const = 0;
};
class ConcreteStrategy1 : public Strategy {
public:
int execute(int x, int y) const override
{
return x + y;
}
};
class ConcreteStrategy2 : public Strategy {
public:
int execute(int x, int y) const override
{
return x - y;
}
};
class Context {
Strategy &strategy;
public:
Context(Strategy &strategy) : strategy {strategy}
{
}
void setStrategy(Strategy &strat)
{
this->strategy = strat;
}
void doLogic() const
{
std::cout << strategy.execute(7, 5) << std::endl;
}
};
int main()
{
ConcreteStrategy1 strat;
Context context {strat};
context.doLogic();
ConcreteStrategy2 strat2;
context.setStrategy(strat2);
context.doLogic();
return 0;
}
You are trying to reassign a reference, but references cannot be reassigned. It assigns to Strategy object being referred to instead. If you make Strategy non-copyable/assignable that re-assignment through reference will fail to compile.
Use a pointer instead:
class Context {
Strategy* strategy;
public:
Context(Strategy &strategy) : strategy {&strategy} {}
void setStrategy(Strategy &strat) { this->strategy = &strat; }
void doLogic() const { std::cout << strategy->execute(7, 5) << std::endl; }
};
Using reference members is almost always a mistake because it breaks value semantics, as you observe. One can get away with using reference members in non-copyable classes.
Additional solution to Maxim Egorushkins answer.
You could also use std::reference_wrapper instead of a pointer:
class Context {
std::reference_wrapper<Strategy> strategy;
public:
Context(Strategy &strategy) : strategy {strategy} { }
void setStrategy(Strategy &strat) { this->strategy = strat; }
void doLogic() const { std::cout << strategy.get().execute(7, 5) << std::endl; }
};
Here are both versions next to each other:
https://gcc.godbolt.org/z/dveK9T
I made a bidirectional and 2-dimensional linked list. My nodes are called chunks, and they contain a pointer to the chunks on their left, right, bottom and top.
class chunk;
typedef std::shared_ptr<chunk> chunk_ptr;
typedef std::weak_ptr<chunk> chunk_wptr;
class chunk
{
public:
chunk(wanted_id) : id(wanted_id) {}
chunk_ptr left() const { return _left.lock(); }
chunk_ptr right() const { return _right.lock(); }
chunk_ptr top() const { return _top.lock(); }
chunk_ptr bottom() const { return _bottom.lock(); }
void left(const chunk_ptr set) { _left = set; }
void right(const chunk_ptr set) { _right = set; }
void top(const chunk_ptr set) { _top = set; }
void bottom(const chunk_ptr set) { _bottom = set; }
int id() const { return _id; }
private:
chunk_wptr _left, _right, _top, _bottom;
int _id;
void id(const int id) { _id = id; }
};
Now, let's imagine that I have built the following structure:
If I want to navigate from 1 to 4, I could use the following line of code:
id4 = id1->right()->right()->bottom();
Now let's imagine that chunk 3 has been removed, e.g. id2->right == id4->top == nullptr:
If I want to access id4 then to perform some operation on it, there will be a runtime error. To avoid to perform a check at each step, I would like to introduce a neutral chunk element:
auto null_chunk = std::make_shared<chunk>(-1); // Let's define its id as -1
null_chunk->left(null_chunk);
null_chunk->right(null_chunk);
null_chunk->top(null_chunk);
null_chunk->bottom(null_chunk);
Thus, the following statement would run succesfully:
id4 = id1->right()->right()->bottom();
And then id4 == null_chunk.
However, I'm not quite sure about how to integrate such an element in my code.
I could use a static variable:
// This is a public static method
chunk_ptr chunk::null_chunk()
{
static auto ptr = instanciate_null_chunk();
return ptr;
}
// This is a private static method
chunk_ptr chunk::instanciate_null_chunk()
{
auto ptr = std::make_shared<chunk>(-1);
ptr->left(ptr);
ptr->right(ptr);
ptr->top(ptr);
ptr->bottom(ptr);
return ptr;
}
Now, I would like to initialize left, right, top and bottom by null_chunk in my constructor:
chunk(wanted_id) : id(wanted_id)
{
this->left(null_chunk());
this->right(null_chunk());
this->top(null_chunk());
this->bottom(null_chunk());
}
This leads to a a recursion stack overflow (null_chunk calling the constructor calling null_chunk etc...).
This forces me to define a specific private constructor for null_chunk(), but because I'm using shared pointers, my constructor must be public to use make_shared...
Thus, there is a design flow. What would be the best way to implement such a feature?
One possible to solution to implement the null node is to use a static member. This member is initialized once using another static function, that creates a shared pointer with the null chunk and redirects all outgoing connections to the chunk itself.
On construction of any other chunk all outgoing connections point to the null chunk as well.
As mentioned in the comments above, make sure not to leak any memory due to circular references.
You have to create a second constructor as you mentioned. However using a private struct as argument prevents any calls to this constructor from outside the class.
class chunk {
public:
using chunk_ptr = std::shared_ptr<chunk>;
using chunk_wptr = std::weak_ptr<chunk>;
private:
int _id;
chunk_wptr _left, _right, _top, _bottom;
static chunk_ptr nullchunk;
struct pctor {};
static chunk_ptr gennull() {
chunk_ptr pnullchunk {std::make_shared<chunk>(pctor{})};
pnullchunk->_left = pnullchunk;
pnullchunk->_right = pnullchunk;
pnullchunk->_top = pnullchunk;
pnullchunk->_bottom = pnullchunk;
return pnullchunk;
}
public:
chunk(pctor) : _id(-1) {}
chunk(int id) : _id(id),
_left(chunk::nullchunk),
_right(chunk::nullchunk),
_top(chunk::nullchunk),
_bottom(chunk::nullchunk) {}
bool isNullNode() const
{ return this == chunk::nullchunk.get(); }
//
// Further functions omitted
//
};
chunk::chunk_ptr chunk::nullchunk {chunk::gennull()};
Title does not help im sure.
Anyway, at the moment i'm working with the following
http://puu.sh/7wJed.png
Everything's fine and inherited correctly, however, in order to create an object of say 'aircraftCarrier' i'd need to pass the 12 values + the two inherited values every-time i want to use a function such as
generateAirCraftCarrier(1,2,3,4,5,6,7,8,9,10,11,12);
I could simply pass in a navalVessel instance into the function instead, such that
generateAirCraftCarrier(myNavalVessel, inherit var 1, inherit var 2);
BUT this would not be entirely a solution because what happens when the aircraft carrier has a different 'Speed' for example?
can i have option parameters, which if null use the myNavalVessel object? Looking for some guidance here, sorry about the gibberish.
Why do you need one function to define all 12 values on an AircraftCarrier? Why not build it up with a number of setters on AircraftCarrier and NavalVessel? e.g:
class NavalVessel {
float speed_;
public:
void setSpeed(float speed) { speed_ = speed; }
};
class AircraftCarrier : public NavalVessel {
int noHeliPads_;
int noRunways_;
public:
void setNoHeliPads(int noHeliPads) { noHeliPads_ = noHeliPads; }
void setNoRunways(int noRunways) { noRunways_ = noRunways; }
};
int main() {
AircraftCarrier aircraftCarrier;
aircraftCarrier.setSpeed(25.3);
aircraftCarrier.setNoHeliPads(3);
aircraftCarrier.setNoRunways(2);
}
Could named parameters idiom be useful for you?
class AircraftCarrierParameters;
class AircraftCarrier
{
private:
AircraftCarrierParameters _params;
public:
AircraftCarrier(const AircraftCarrierParameters& params)
: _params(params) {}
AircraftCarrierParameters params() const { return _params;}
};
class AircraftCarrierParameters
{
private:
double _speed;
int _someOtherStuff;
public:
AircraftCarrierParameters()
: _speed(0) //default parameters
, _someOtherStuff(0)
{
}
double speed() const { return _speed; }
double someOtherStuff() const { return _someOtherStuff; }
AircraftCarrierParameters& setSpeed(double speed) { _speed = speed; return *this; }
AircraftCarrierParameters& setSomeOtherStuff(double stuff) { _someOtherStuff = stuff; return *this; }
};
AirCraftCarrier generateAirCraftCarrier(const AircraftCarrierParameters& params)
{
//...
}
void main()
{
AircraftCarrier c1(AircraftCarrierParameters());
AircraftCarrier c2(c1.params().setSpeed(30));
}
Say I have a class with a couple of data members, and I want a class method that returns one, and the next time it is called returns the value of the other. Something like:
class MyClass
{
public:
MyClass():switch(0){};
int get();
private:
int intA, intB;
int sw;
};
int MyClass::get()
{
if ( (++sw)%2 )
return intA;
else
return intB;
}
What would a more elegant way of doing it be? I don't like the if...else statement very much. It's fine for something like return, but if I'm actually using more complex operations, I end up duplicating a ton of code. Or having to create a second method within each method that is called after I resolve what element I'm pointing to.
What I'd prefer to do, ideally, is to use some form of pointer, so I can do
class MyClass
{
public:
MyClass():switch(&intA){};
int get();
void toggleSwitch();
private:
int intA, intB;
int * sw;
};
int MyClass::get()
{
return *sw;
}
void MyClass::toggleSwitch()
{
if ( sw == &intA )
sw = &intB;
else
sw = &intA;
}
Or something to that effect. I could call toggleSwitch(), and have my class operate on either one or the other value easily.
I still don't like it though. I prefer to avoid if's when possible, and I shouldn't need one in this case. This use of a naked pointer should be pretty safe, but I was thinking I could have something like std::unique_ptr holding each element and then std::swap them. But then the pointers would own the elements, and they'd be dynamic memory instead.
So is there a better way to do it?
Well, switch is a keyword, but I'll roll with it. How about an array of pointers?
int *fields[] = {&intA, &intB};
int MyClass::get()
{
return *fields[++switch % 2];
}
This would expand nicely if you could have additional variables later.
Or maybe:
int MyClass::get()
{
return *fields[switch = 1 - switch];
}
If you return a reference then you could use get() internally.
int &MyClass::get()
{
return *fields[switch = 1 - switch];
}
I would encapsulate the concept of a toggling value:
template<typename T>
class Toggleable {
T first;
T second;
T* current;
T* other;
public:
Toggleable(const T& first, const T& second)
: first(first),
second(second),
current(&first),
other(&second) {
}
bool toggle() {
std::swap(current, other);
}
const T& get() const {
return *current;
}
}
Then use as:
class MyClass
{
Toggleable<int> value;
public:
MyClass()
: value(42, 1729)
{
}
const int& get() {
value.toggle();
return value.get();
}
};
Sorry for the long title but I did want to be specific.
I expected the following code to work but it doesn't and I can't figure out why :/
#include <cstdio>
#include <cassert>
class UniquePointer
{
public:
void Dispose()
{
delete this;
}
friend void SafeDispose(UniquePointer*& p)
{
if (p != NULL)
{
p->Dispose();
p = NULL;
}
}
protected:
UniquePointer() { }
UniquePointer(const UniquePointer&) { }
virtual ~UniquePointer() { }
};
class Building : public UniquePointer
{
public:
Building()
: mType(0)
{}
void SetBuildingType(int type) { mType = type; }
int GetBuildingType() const { return mType; }
protected:
virtual ~Building() { }
int mType;
};
void Foo()
{
Building* b = new Building();
b->SetBuildingType(5);
int a = b->GetBuildingType();
SafeDispose(b); // error C2664: 'SafeDispose' : cannot convert parameter 1 from 'Building *' to 'UniquePointer *&'
b->Dispose();
}
int main(int argc, char* argv[])
{
Foo();
return 0;
}
Imagine it were legal. Then you could write code like this:
class Animal : public UniquePointer
{
};
void Transmogrify(UniquePointer*& p)
{
p = new Animal();
}
void Foo()
{
Building* b = nullptr;
Transmogrify(b);
b->SetBuildingType(0); // crash
}
Observe that you have violated the type system (you put an Animal where a Building should be) without requiring a cast or raising a compiler error.
I do not think that it is possible to make it work the way you have it designed. Instead, try the following:
template <typename T>
void SafeDispose(T * & p)
{
if (p != NULL)
{
p->Dispose();
p = NULL;
}
}
class UniquePointer
{
public:
void Dispose()
{
delete this;
}
protected:
UniquePointer() { }
UniquePointer(const UniquePointer&) { }
virtual ~UniquePointer() { }
};
It is not allowed because if it were you could do the following:
friend void SafeDispose(UniquePointer*& p)
{
p = new UniquePointer();
}
Building* building;
SafeDispose(building)
//building points to a UniquePointer not a Building.
I guess the work around would be a template function.
To answer the title of your question, you cannot bind a non-const reference to base to a derived class instance because you could then set that reference to a pointer to a base instance that isn't a derived. Consider this function:
void Renew(UniquePointer *& p) {
delete p;
p = new UniquePointer();
}
if you could pass it a pointer to Building you would be able to set it incorrectly to point to a UniquePointer instance.
As it has already been suggested the solution is to change your reference to a plain pointer. Not only this solves your problem, but it is also a better implementation of SafeDispose(); as you wrote it this function gave the false idea that you would always set to 0 all your UniquePointer instances. But what would happen if somebody wrote (assuming UniquePointer constructor was public for simplicity):
UniquePointer *p1 = new UniquePointer();
UniquePointer *p2 = p1;
SafeDispose(p1);
They would expect all of their UniquePointers to be properly taken care of, when p2 is actually invalid.
I guess your SafeDispose should probably look more like :
friend void SafeDispose(UniquePointer** p) ...
In order to invoke it using
SafeDispose(&(UniquePointer*)b);
Then it should work this way.
But your next statement
b->Dispose();
will break cause b should now be NULL, cause it has been disposed and set to NULL by your SafeDispose method.