How to pass one static object around multiple classes? - c++

I'm having trouble implementing an ImageManager into my program. I had success using this method with references:
//definition in Brick.h
ImageManager &imgr;
//constructor taking &imgr as a reference upon creation of object
Brick::Brick(ImageManager &im) : imgr(im){
//imgr is now a reference in my class, so it points to the same object that imgr in another class would point to
//this essentially makes one "static" instance of imgr, so all my graphic objects are dealing with the same instance of my ImageManager
imgr.doStuff()
}
This method of passing around my imgr used to work, until I started trying to remove obejcts from vectors. For instance, in my Level class I try to remove elements from a vector of Brick objects,
void Level::RemoveLine(int line){
//loop through every piece, loop through given piece's rects, if the rect falls on the removed line, then remove the piece
for(int i = 0; i < gamePieces_.size(); i++){
//crt new iterator per each gamepiece
auto write = gamePieces_[i].GetPieceRectangles().begin();
int j = 0;
for(auto read = write; read != gamePieces_[i].GetPieceRectangles().end(); read++){
if(gamePieces_[i].GetPieceRectangles()[j].GetActiveLine() != line){
if(read != write){
write = std::move(read);
}
write++;
}
}
gamePieces_[i].GetPieceRectangles().erase(write, gamePieces_[i].GetPieceRectangles().end());
}
}
but this doesn't work because ImageManager &imgr declared in Brick.h doesn't have a copy constructor, so it can't be copied in vectors when I try to .erase() the element. My goal is to implement one static ImageManager object to be used throughout all my classes. How would I go about doing this?

"My goal is to implement one static ImageManager object to be used throughout all my classes"
You can implement ImageManager as Singleton class. But I have learnt to use singleton only if there's no other option.
You can also use static data members in your class. In this way only one copy of your class's data members would be in circulation.

Generally speaking this kind of code isn't what you want. Take a look at the Singleton design pattern.
https://en.wikipedia.org/wiki/Singleton_pattern

Related

Saving a pointer vs passing value as const

This is something from the theory of c++ which I never quite got.
I have very large list of small structures (in size) called nodes inside Class A.
So I have:
private:
QList<Node> nodes;
Now Class A has instance of Class B (called cB) and for one of its functions it requires to iterate over nodes and just read them (it will not modify the information in any way).
function ClassB::readNodes(){
for (int i = 0; i < nodes.size(); i++){
// READ nodes and do stuff with that information
}
}
So as far as I know there two ways to approach this. This is my current approach Inside Class B I have:
public:
void setNodes(const QList *list) {nodes = list;}
private:
QList<Node> *nodes;
And then somewhere in Class A I do:
cb.setNodes(&nodes);
The objective of this approach is that I want to avoid copying a very large data structure each time readNodes() is called, and also there is only one copy of the data structure in memory. This is important because Class A will continually change nodes.
The second approach is much simpler and more clear in my opinion. Simply define readNodes as:
function ClassB::readNodes(const QList<Node> &nodes){
for (int i = 0; i < nodes.size(); i++){
// READ nodes and do stuff with that information
}
}
But I'm not totally sure that this will insume a performance penalty. As far as I understand it this approach also treats nodes as a reference and so no deep copy of nodes occurs. Is this correct?
Most of the Qt classes(including container classes) are implicitly shared. So even if you pass them around by value, there won't be a deep copy until you access to those items.
Passing const references of objects is a more general and safe approach though.

Why do they say that in the Proto-type Pattern - be used to simply duplicate the original object whenever a new one is needed?

I am trying to learn the design pattern. I am a C++ programmer. Currently, I am juggling with the Proto-type pattern. I could co-relate Prototype with the factory type. However, there are a lot of differences between factory and prototype pattern. For example, in the prototype pattern each derived class registers its prototype with the base/super class.
However, looking at the wikipedia article - I couldn't understood the following points.
Rather than retrieving the data and re-parsing it each time a new object is created, the prototype pattern can be used to simply duplicate the original object whenever a new one is needed.
avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword) when it is prohibitively expensive for a given application.
Here is the program, I created to demonstrate the prototype pattern in C++. However, I cannot find any benefit out of it. How come a prototype pattern will help in quickly creating the object here. I can see that the object has to call 'new' every time. Here is the entire program, please correct me if you think that I haven't implemented the prototype pattern correctly.
Sorry for the long program - but trust me it is quite simple.
Like a factory object - here is the prototype class
-- basically an abstract.
class Itransport
{
public:
enum transportPacketType
{
udp,
tcp,
MAX
};
private:
static std::list<Itransport *> prototypesList;
protected:
virtual Itransport::transportPacketType getPacketType() = 0;
virtual Itransport* clone() = 0;
/** This will be called by the derived classes **/
static void registertoPrototypeList(Itransport *packet)
{
prototypesList.push_back(packet);
}
public:
virtual void showMessage() = 0;
static Itransport* makeClone(Itransport::transportPacketType packType)
{
std::list<Itransport *>::iterator it;
for(it = prototypesList.begin(); it != prototypesList.end(); it++)
{
if( (*it)->getPacketType() == packType )
{
return (*it)->clone();
}
}
}
virtual ~Itransport() = 0;
};
Itransport::~Itransport()
{
std::cout<<"Itransport Destructor called"<<std::endl;
}
std::list<Itransport *> Itransport::prototypesList;
Here is the concrete type of the Itransport Packet -
class udpPacket: public Itransport
{
private:
static udpPacket udpTransportPacket;
protected:
Itransport::transportPacketType getPacketType()
{
return Itransport::udp;
}
Itransport* clone()
{
return new udpPacket();
}
public:
void showMessage()
{
std::cout<<"This is a UDP Packet"<<std::endl;
}
udpPacket()
{
std::cout<<"UDP Packet Constructed"<<std::endl;
registertoPrototypeList(this);
}
~udpPacket()
{
std::cout<<"Destructor of udp called"<<std::endl;
}
};
static udpPacket udpTransportPacket;
Here is the client -
int main()
{
Itransport *udpPacket;
Itransport *udpPacket2;
udpPacket = Itransport::makeClone(Itransport::udp);
udpPacket->showMessage();
udpPacket2 = Itransport::makeClone(Itransport::udp);
udpPacket2->showMessage();
delete udpPacket;
delete udpPacket2;
return 0;
}
I couldn't find any benefits related to 'new' here. Please throw some light on it.
I can have a go at explaining the first point:
Rather than retrieving the data and re-parsing it each time a new
object is created, the prototype pattern can be used to simply
duplicate the original object whenever a new one is needed.
Imagine a computer game that has to create a lot of monsters. Say all the different types of monster are not known at compile time but you construct a monster of a particular type from some input data that provides information about what color the monster is, etc:
class Monster {
public:
Monster(InputDataHandle handle) {
// Retrieve input data...
// Parse input data...
}
void setPosition(Position);
};
Then every time you want to construct, say a red monster you have to retrieve the data and re-parse:
// Spawn a lot of red monsters
for (int i = 0; i != large_number; ++i) {
auto red = new Monster(red_monster_data); // Must retrieve data and re-parse!
red->setPosition(getRandomPosition());
game.add(red);
}
Clearly that is inefficient. One way of solving it is using the Prototype Pattern. You create one "prototype" red monster and every time you want to create an instance of a red monster you simply copy the prototype and you don't have to retrieve and re-parse the input data:
auto prototype_red_monster = new Monster(red_monster_data);
for (int i = 0; i != large_number; ++i) {
auto red = prototype_red_monster->clone();
red->setPosition(getRandomPosition());
game.add(red);
}
But how is the clone function implemented? This brings us to the second point which I don't really understand:
avoid the inherent cost of creating a new object in the standard way
(e.g., using the 'new' keyword) when it is prohibitively expensive for
a given application.
The clone function fundamentally has to allocate memory for the new object and copy data in from itself. I'm not sure I know what they are referring to when they talk about the "inherent cost of the new keyword". The examples are in Java and C# which have clone() and MemberwiseClone() respectively. In those languages you don't need to call new. I don't know how clone() and MemberwiseClone() are implemented but I don't see how they can "avoid the inherent cost of the new keyword".
In C++ we have to implement clone() ourselves and it will typically use new and use the copy constructor:
Monster* clone() {
return new Monster(*this);
}
In this case the copy constructor is much cheaper than creating the object from scratch. In your case it might not be.
The fact you cannot find any benefit from the Prototype Pattern in your case might mean it is the wrong pattern for your case and you will be better off with a different pattern like the Object Pool, Flyweight or Abstract Factory Pattern.

Creating a new object by calling the new constructor with a string

I was recently in a job interview and my interviewer gave me a modeling question that involved serialization of different shapes into a file.
The task was to implements shapes like circle or rectangles by first defining an abstract class named Shape and then implements the various shapes (circle, rectangle..) by inheriting from the base class (Shape).
The two abstract methods for each shape were: read_to_file (which was supposed to read the shape from a file) and write_to_file which supposed to write the shape into a file.
All was done by the implementation of that virtual function in the inherited shape (Example: For Circle I was writing the radius, for square I saved the side of the square....).
class Shape {
public:
string Shape_type;
virtual void write_into_file()=0;
virtual void read_into_files()=0;
Shape() {
}
virtual ~Shape() {
}};
class Square: public Shape {
public:
int size;
Square(int size) {
this->size = size;
}
void write_into_file() {
//write this Square into a file
}
void read_into_files() {
//read this Square into a file
}
};
That was done in order to see if I know polymorphism.
But, then I was asked to implement two functions that take a vector of *shape and write/read it into a file.
The writing part was easy and goes something like that:
for (Shape sh : Shapes) {
s.write_into_file();
}
as for the reading part I thought about reading the first word in the text (I implemented the serializable file like a text file that have this line: Shape_type: Circle, Radius: 12; Shape_type:Square...., so the first words said the shape type). and saving it to a string such as:
string shape_type;
shape_type="Circle";
Then I needed to create a new instance of that specific shape and I thought about something like a big switch
<pre><code>
switch(shape_type):
{
case Circle: return new circle;
case Square: return new square
......
}
</pre></code>
And then, the interviewer told me that there is a problem with this implementation
which I thought was the fact that every new shape the we will add in the future we should also update int that big swicht. he try to direct me into a design pattern, I told him that maybe the factory design pattern will help but I couldn't find a way to get rid of that switch. even if I will move the switch from the function into a FactoryClass I will still have to use the switch in order to check the type of the shape (according to the string content i got from the text file).
I had a string that I read from the file, that say the current type of the shape. I wanted to do something like:
string shape_type;
shape_type="Circle";
Shape s = new shape_type; //which will be like: Shape s = new Circle
But I can't do it in c++.
Any idea on what I should have done?
In you factory you could map a std::string to a function<Shape*()>. At startup you register factory methods will the factory:
shapeFactory.add("circle", []{new Circle;});
shapeFactory.add("square", []{new Square;});
shapeFactory.add("triangle", []{new Triangle;});
In your deserialization code you read the name of the type and get its factory method from the factory:
std::string className = // read string from serialization stream
auto factory = shapeFactory.get(className);
Shape *shape = factory();
You've now got a pointer to the concrete shape instance which can be used to deserialize the object.
EDIT: Added more code as requested:
class ShapeFactory
{
private:
std::map<std::string, std::function<Shape*()> > m_Functions;
public:
void add(const std::string &name, std::function<Share*()> creator)
{
m_Functions.insert(name, creator)
}
std::function<Shape*()> get(const std::string &name) const
{
return m_Functions.at(name);
}
};
NOTE: I've left out error checking.
In C++, with
for (Shape sh : Shapes) {
s.write_into_file();
}
you have object slicing. The object sh is a Shape and nothing else, it looses all inheritance information.
You either need to store references (not possible to store in a standard collection) or pointers, and use that when looping.
In C++ you would to read and write some kind of type tag into the file to remember the concrete type.
A virtual method like ShapeType get_type_tag() would do it, where the return type is an enumeration corresponding to one of the concrete classes.
Thinking about it, though, the question was probably just getting at wanting you to add read and write functions to the interface.
You could create a dictionary of factory functions keyed by a shape name or shape id (shape_type).
// prefer std::shared_ptr or std::unique_ptr of course
std::map<std::string, std::function<Shape *()>> Shape_Factory_Map;
// some kind of type registration is now needed
// to build the map of functions
RegisterShape(std::string, std::function<Shape *()>);
// or some kind of
BuildShapeFactoryMap();
// then instead of your switch you would simply
//call the appropriate function in the map
Shape * myShape = Shape_Factory_Map[shape_type]();
In this case though you still have to update the creation of the map with any new shapes you come up with later, so I can't say for sure that it buys you all that much.
All the answers so far still appear to have to use a switch or map somewhere to know which class to use to create the different types of shapes. If you need to add another type, you would have to modify the code and recompile.
Perhaps using the Chain of Responsibility Pattern is a better approach. This way you can dynamically add new creation techniques or add them at compile time without modifying any already existing code:
Your chain will keep a linked list of all the creation types and will traverse the list until it finds the instance that can make the specified type.
class Creator{
Creator*next; // 1. "next" pointer in the base class
public:
Creator()
{
next = 0;
}
void setNext(Creator*n)
{
next = n;
}
void add(Creator*n)
{
if (next)
next->add(n);
else
next = n;
}
// 2. The "chain" method in the Creator class always delegates to the next obj
virtual Shape handle(string type)
{
next->handle(i);
}
);
Each subclass of Creator will check if it can make the type and return it if it can, or delegate to the next in the chain.
I did create a Factory in C++ some time ago in which a class automatically registers itself at compile time when it extends a given template.
Available here: https://gist.github.com/sacko87/3359911.
I am not too sure how people react to links outside of SO but it is a couple of files worth. However once the work is done, using the example within that link, all that you need to do to have a new object included into the factory would be to extend the BaseImpl class and have a static string "Name" field (see main.cpp). The template then registers the string and type into the map automatically. Allowing you to call:
Base *base = BaseFactory::Create("Circle");
You can of course replace Base for Shape.

Sharing the same container between two different classes

Say for example I have the following two classes:
class ChessBoard
{
std::vector <ChessPiece> pieceList;
}
class ChessSquare
{
std::vector <ChessPiece> pieceList;
}
What I want to do is allow both classes to have access to the exact same ChessPiece vector, so that both of them have read/write access to the EXACT SAME ChessPiece data. So say for example when ChessSquare updates the pieceList vector, the corresponding pieceList vector in ChessBoard will get updated as well, and vice-versa. How would I go about implementing this?
Use a pointer. Give them each a copy of the same pointer to the vector.
If you give them each a std::shared_ptr you get the added benefit of reference counting and cleanup handled once neither of the classes are left using it.
Use pointer or reference to the pieceList.
Create object ChessPiece and send pointer of this object to ChessBoard and ChessSquare. I hope you access to ChessPiece only from one thread, instead you have to protect your ChessPiece using mutex or something like that.
Pointer is the obvious choice. BUT if you are feeling crazy and want to over-engineer your project you could encapsulate the vector within its own class and make that class a globally visible singleton
Use pointer maybe a good way, but i think you should achieve your point like this:
class ChessBase
{
static std::vector <ChessPiece> pieceList;
}
class ChessBoard : ChessBase
{
//to do what you want.
}
class ChessSquare : ChessBase
{
//to do what your want.
}
You can access the vector in each class as their member.
Seeing as a chessboard is composed of chess squares, I might suggest having the vector in the chessboard class and a reference to it in the chess square class, maybe like so:
typedef std::vector<ChessPiece> PIECES
class ChessBoard
{
public:
ChessBoard()
{
// NOTE! your app might have more squares than this:
m_pSquare = new ChessSquare( pieceList );
}
private:
PIECES pieceList;
ChessSquare* m_Square;
}
class ChessSquare
{
public:
ChessSquare( const PIECES& pieces )
: refPieceList(pieces)
{
}
private:
const PIECES& refPieceList;
}

C++ Class with member varialble vector <another class>

I have an assignment to make Information system about resorts in a country, be able to read/write data for the resorts from/to file and modifying it.
class CTŠ¾urist{
string m_StrName;
string m_StrCountry;
int m_iAge;
public:
//constructors, mutators, accessors overloading operator <<,>>
};
I don't have problem writing this class. And here I have class which contains as member variable vector of the first class's objects
class CHotel
{
string m_strHotelName;
int m_iNumberOfBets;
double m_dAveragePrice; //average price per bet in the hotel
vector <CTourist> m_vecTourists; //vector of tourists rested in the hotel
public:
.....
};
And one more class Resort containing as member variable vector of the second class's objects
class CResort
{
string m_ResortName;
unsigned m_Height;
vector<CHotel*> m_Hotels;
public:
.....
};
So here is the problem. I'm not sure how to write the accessor,mutator and constructors for that vector variable so I can use them property. Thank you for checking and if someone could help me figure out these functions I'll be really grateful!
if i understand correctly you want to know the best way to get your hotels from cResort.
i would recommend
cHotel* GetHotelByName(std::string& a_sName)
{
for(int i = 0; i < m_Hotels.size(); ++i)
{
if(m_Hotel[i].GetName() == a_sName)
return m_Hotel[i]
}
return nullptr; // if non found return return null
}
and add a GetName function to your hotel class which returns a string of its name.
this also allows you to SetName etc.
1) Accessor, mutator: There are plenty of options.
You can create another class like CTouristList (and CHotelList respectively), that wraps the vector, have it referenced from the CHotel class (accessor methods like CTouristList& CHotel::GetTouristList() and const CTouristList& CHotel::GetTouristList() const) and implement methods like CTouristList::Add, CTouristList::Remove, CTouristList::Get, etc.
Or you can add methods like CHotel::AddTourist() directly on the CHotel class.
2) Constructor. Nothing needed in constructor. But for vector<CHotel*> you may need destructor in CResort to explicitly free the CHotel instances. Though not sure why you want to use pointers to CHotel.
You can put the accessor and mutator functions in CTourist just like you would if they were not being stored in a Vector.
To utilize them once they are in CHotel you could add a function in CHotel that returns a pointer to a CTourist.
// Access a CTourist
Hotel.getTourist(1)->setName("Tourist name");
Adding a method that returns the number of tourist that visited a hotel would make it easier to loop through them.
for(int i = o; i < Hotel.touristCount(); ++i)
{
// Do something useful
std:: cout << "Hello " << Hotel.getTourist(i)->getName();
}
In that case your CHotel::touristCount() would be a wrapper around the vector<>.size();
If you do not want code outside of CHotel to have direct access to a CTourist object then create wrapper functions in CHotel that do what you would want to do externally.
i.e.
std::cout << Hotel.getTouristName(1);
instead of
std::cout << Hotel.getTourist(1)->getName();