Is it better to update the value or change the pointer? - c++

C++
Is it better to update the value of a pointer or to change the pointer to point to something else?
Let's say we have two classes: ball and coordinates.
class ball
{
Coordinates *ballCurrent;
public:
ball(int);
~ball();
void setLoc(Coordinates&); // OR void setLoc(int, int);
};
class Coordinates
{
int x, y;
public:
Coordinates(int, int);
void setCoordinates(int, int);
};
For the setLoc method in the ball class, which parameters should is better? Would it be better to just setLoc by using (*ballCurrent).setCoordinates(int, int) OR by using (ballCurrent).setLoc((new Coordinates(int, int)))? Please go into detail the reason for each case if possible.

Is it better to update the value of a pointer or to change the pointer
to point to something else?
That's not the sort of question that can be answered without some context. It's often useful to know that an object is immutable -- that as long as you have a pointer to that object, the object won't change under your nose. For example, if a function or method takes a pointer to an immutable type as a parameter, you know that you can pass objects to that function without worrying that the function will change the object.
On the other hand, mutable objects also have their place. For one thing, you sometimes want to be able to build an object up in several steps rather than doing it all at once, and you may not want to have to create several intermediate objects along the way just to get to the final object.
So, it depends on context. I see that you've provided a simple example, but I don't think there's necessarily a correct answer even for your example. It depends on what's important to you and how the objects in question will interact with other parts of the system. I'd lean toward mutable objects, I think, because in a game it's likely that several objects will need to know about the ball. If the only way to move the ball is to create a new ball and pass it around to all the other objects that care about it, well, that could easily get to be a huge problem. The coordinates object could easily be immutable, though -- anyone who needs to know the location of the ball should ask the ball for it's location. Once they get it, they'll probably expect the location not to change every few milliseconds. If you don't make the coordinates object immutable, the other way to handle that problem is for the ball to make a copy of its location whenever someone asks, and hand out that copy instead of returning a pointer to its own location object.

I might write this way if I could:
class ball
{
Coordinates coordinate_; // better name than ballCurrent?
public:
explicit ball(int) // add explicit to avoid implicit converting
: coordinate_(0,0) // initialize corrdinate_ properly
{
}
~ball();
void setLoc(const Coordinates& co) // add const
{
coordinate_ = co;
}
void setLoc(int x, int y)
{
coordinate_.setCoordinates(x,y);
}
};
No need to worry about dynamic memory issue, could setLoc in two ways by function overloading. No wild pointer, no worries.

If you use a new object, it will need memory allocated for itself, and it will also need to be initialized (constructor/s run, properties assigned, etc). That is a lot of overhead compared to just change the value of an object you already have (and that you created for that very purpose).
Besides, if you create a new object, you need to free the memory of your previous pointer, which again is overhead... so just change your existing object.

Just change the values of the object that is being pointed to. It doesn't make sense to create a whole new object every time you want to update a value.
One situation where you might have to create a whole new object rather just change the values is if Coordinates had a const x and y value and there was no setCoordinates function. But then that's mostly likely a poor design decision if you are needing to be update the co-ordinates often.
Also rather than this:
(*ballCurrent).setCoordinates(int, int);
you can use this:
ballCurrent->setCoordinate(int, int);
Which does the same thing but is just easier to write and a lot of people will find it more readable.

In the case of SetLoc(int,int), you are creating a dependency between ball and Coordinates on the Coordinates constructor, and more importantly, on what it represents. If the constructor signature changes, you will have to carry these changes over to ball::SetLoc. This argument is valid in the general case, where you really want to avoid passing along a set of parameters to initialize an object component.
In this particular case, Coordinates embodies an position in space, and probably should come with a set of methods to manipulate it, in order to preserve its implementation details from pervading the rest of the programme. If you wish to move to a 3D coordinate system, ideally, all you would have to change are the constructors invocations and the class implementation. So you really want to reduce the necessary changes outside the class to a minimum, which means avoiding the issue explained earlier.
You present two different solutions to set the location of the ball object. In practice would these solutions appear? In a trivial programme, where the ball position hardcoded, that is a possibility, and either solution could work. But in a more sophisticated software, the ball position would probably be initially set by a configuration file, and any subsequent update of the position done after some non trivial computation. In this situation, it much more maintainable to encapsulate all the logic pertaining to coordinates in the class, and avoid the (int, int) parameter passing.
If you are concerned by memory allocation overheads (e.g. temporaries generated by function returned results), there are ways to alleviate them by using wisely consts, references, or even pointers, and define sensible copy constructors.

Related

How do I go about allowing an object of a class type to be uninitialized and identifying when this is the case without using a pointer?

I recently found out for the past few years of me using C++, I have been using pointers far too often and usually when I could easily substitute them for something more appropriate. Something I used them for was using one to allow an object to be uninitialized, and easily check so.
For example, let's say I have a camera that I want to be attaching to an object in a game:
Class Camera {
public:
Entity *attachEntity;
Camera() {
attachEntity = nullptr;
}
void update() {
// If there's an entity to be attached to
if (attachEntity != nullptr) {
...
}
}
};
Is this a bad usage of a pointer? I can't find a good way of doing this without using one. And if it's not supposed to be attached to the entity, you can just set it to nullptr again if it's a pointer. Otherwise, there needs to always be an attachEntity, despite whether or not the camera is attached to it at the moment. Is there anything wrong with this practice? Is there a good way to do this without pointers? I saw that you can't just set an object to NULL like you can a pointer. What's the best way of doing this?
If you want value semantics but still need to be able to omit a
value, you can use std::optional.
You get similar behavior with a std::unique_ptr, except that
the Entity takes up no space when absent but otherwise goes into its
own block of dynamically-allocated memory.
If you want non-owning reference to an Entity instance whose
lifespan will exceed that of the Cameria instance, a raw pointer is
appropriate.
When the Entity is potentially used by multiple Cameras (or other
things) and you need to ensure its lifespan is extended until its
last use, that's where std::shared_ptr fits in.
As Michael pointed out, there's also std::weak_ptr, which is
good to know about but typically rare in practice. It's used to
address a shared_ptr without keeping it alive.
(edited to add #5)
Yes.
Use std::shared_ptr which auto-destructs when no longer needed.
And then you forget everything about copy/move constructors in your classes.
Also it initializes itself to nullptr automatically; No need for your constructor then.
You can also use std::unique_ptr if you are sure that your pointer isn't going to be duplicated, for example, when you only have one object of type Camera. Usually I use shared_ptr to allow copies over threads etc.
Class Camera {
public:
shared_ptr<Entity> attachEntity;
void update() {
// If there's an entity to be attached to
if (attachEntity) {
...
}
}
};
Generally, raw pointers are only nowadays useful to call pointer-only functions, like WinAPI etc. That way, your classes won't need copy/move constructors or assignment operators or destructors, unless you want to move/dup an object which is not visible to the language, like a HANDLE in Windows.
Since you want to attach the camera to one specific entity and change the attachment, you need a pointer.
Since the existence of that entity should be independent of the camera, a raw pointer is appropriate.
If all your entities are shared (as shared_ptrs), a weak_ptr would be best, but it’s not obvious that they should be.
Your solution for the camera is perfectly valid. All the other answers take a long way around of telling you you're doing the right thing by pointing you to shared pointers and optional types, but storing the attach entity as a pointer and using it the way you are is exactly how you would expect it to be done.
I'm going to have some haters, but I personally HIGHLY encourage the use of raw pointers (instead of smart/shared pointers) for real-time applications :).

Should I use reference member to deal with dependency between objects?

As a beginner in C++, I am practicing C++ with an algorithm assignment. Along the way, I have some questions that I have difficulty getting through. Pardon me if the questions sound entry-level since I am still learning.
The goal is to find collinear points in a given vector of points with three classes. The following briefly describes the three classes' purposes:
Point: Representing a point with x and y values.
LineSegment: Representing a line segment with two points at ends.
Collinear: Containing the segments found in a vector of Points. The main part of the algorithm.
So, I would expect the client code to look like this:
std::vector<Point> points; // may become huge
// populate points
// ...
Collinear collinear_points(points);
std::vector<LineSegment> segments_in_points = collinear_points.GetSegments();
Since the class Collinear depends on a certain vector of points to get the segments correspondingly, I think it would need it as a data member. The question that keeps haunting me is, should it hold a copy of the vector or hold a raw pointer/reference to the vector outside the object. I think a smart pointer would be an overkill here. According to the old answer here, maybe it is better to go with reference which also avoids potential expensive copying? What is the common practice for this kind of dependency between classes if any exists?
If points gets modified after the construction of collinear_points, then the data collinear_points is referencing will be inconsistent with the segments it contains. Is it common to leave the responsibility to users for making sure the validness of an object depending on other ones? Is there a way to let collinear_points know the content has been modified and put it in an invalid state?
To answer your actual question from the title: A non-owning raw pointer would still be the usual choice, mainly because that’s what we’ve been doing since the old C days. Of course, a pointer has the problem that it can be nullptr. So using a reference communicates more clearly that null is not an allowed value. Because of that I tend to use the reference, although it still feels a tiny bit weird even to myself. But imo it’s the better design decision overall
That said, I believe the real question here is one of ownership. If Collinear does not own the vector, the user of your API has to make sure that the vector lives at least as long as the associated Collinear object. Otherwise you’ll access a dangling pointer/reference and things tend to go downhill from there. ;)
Is there a way to let collinear_points know the content has been modified and put it in an invalid state?
Yes, there is. Own everything. That includes the points vector and the segments vector. Following this approach Collinear could look something like this:
class Collinear {
public:
// usings because I’m a lazy typer
using PointsVec = std::vector<Point>;
using SegmentsVec = std::vector<LineSegment>;
// Take ownership of the points vector by either copying
// or moving it into a member.
explicit Collinear(const PointsVec& p): m_points(p) {}
explicit Collinear(PointsVec&& p): m_points(std::move(p)) {}
// Retain ownership of the segments vector by returning a const ref.
const SegmentsVec& GetSegments(); // Check if you can make it const.
// access functions for the two vectors ...
private:
PointsVec m_points;
SegmentsVec m_segments;
}
Now Collinear controls access to the points vector. You’ll have to write the functions for the permitted operations as members of Collinear. The important thing is never to return a non-const pointer or non-const ref to m_points, because then you might miss write accesses.
The segments vector is similar. Your provide the write access member functions and Collinear retains ownership, which means it can re-calculate it when necessary and the user doesn’t need to be concerned with that. Depending on how expensive the calculation is you can now go wild with lazy evaluation and every optimization you can think of.
There is a completely different design approach, though. Own nothing. Does Collinear have to be a class at all? Could it be a bunch of free functions in a namespace?
namespace Collinear {
std::vector<LineSegment> GetSegments(const std::vector<Point>& points);
}
// ...
auto segments_in_points = Collinear::GetSegments(points);
That’s the opposite of the own-everything approach. Before, you had full control. Now your user has full control. On the other hand, they now have to take care of any laziness/optimizations/update detection.
Which approach is appropriate is a question of a) API design philosophy and b) your conrete situation. What are your users? What do they expect? Which approach makes their lives easier? Since this is an assignment, you probably won’t have any real users. So imagine a group of people that might want to use your code and decide based on that. Or just use the approach you’ll have more fun implementing. The important thing imo: Pick one of the two approaches. Don’t mix them, because such an API is inconsistent. That increases confusion, decreases ease of use, and makes errors more likely.
Btw:
I think a smart pointer would be an overkill here.
Using smart pointers is not a question of overkill. It’s a question of ownership. If you have an owning pointer never use a raw pointer for it. … Unless a legacy API forces you to. Even then it’s a great idea to mark it as owning with a transparent wrapper like gsl::owner<T>.
The question that keeps haunting me is, should it hold a copy of the vector or hold a raw pointer/reference to the vector outside the object
I think you should keep a copy of vector here to keep things generic.You don't want your collinear class depend on a particular vector<Points>, instead it should be like while creating instance of collinear class you just tell it on what vector<Points>, it has to work on.Then if you change this vector and you want collinear also to work on this data set(which you might not want), its your responsibility to tell collinear to work on new data set.If you want collinear to be updated automatically when you update vector<points>, you can do so, but you have to answer questions like what happens to the state of collinear(which would be depending on the vector<points>) when the data set changes.

C++11 Smart Pointer Semantics

I've been working with pointers for a few years now, but I only very recently decided to transition over to C++11's smart pointers (namely unique, shared, and weak). I've done a fair bit of research on them and these are the conclusions that I've drawn:
Unique pointers are great. They manage their own memory and are as lightweight as raw pointers. Prefer unique_ptr over raw pointers as much as possible.
Shared pointers are complicated. They have significant overhead due to reference counting. Pass them by const reference or regret the error of your ways. They're not evil, but should be used sparingly.
Shared pointers should own objects; use weak pointers when ownership is not required. Locking a weak_ptr has equivalent overhead to the shared_ptr copy constructor.
Continue to ignore the existence of auto_ptr, which is now deprecated anyhow.
So with these tenets in mind, I set off to revise my code base to utilize our new shiny smart pointers, fully intending to clear to board of as many raw pointers as possible. I've become confused, however, as to how best take advantage of the C++11 smart pointers.
Let's assume, for instance, that we were designing a simple game. We decide that it is optimal to load a fictional Texture data type into a TextureManager class. These textures are complex and so it is not feasible to pass them around by value. Moreover, let us assume that game objects need specific textures depending on their object type (i.e. car, boat, etc).
Prior, I would have loaded the textures into a vector (or other container like unordered_map) and stored pointers to these textures within each respective game object, such that they could refer to them when they needed to be rendered. Let's assume the textures are guaranteed to outlive their pointers.
My question, then, is how to best utilize smart pointers in this situation. I see few options:
Store the textures directly in a container, then construct a unique_ptr in each game object.
class TextureManager {
public:
const Texture& texture(const std::string& key) const
{ return textures_.at(key); }
private:
std::unordered_map<std::string, Texture> textures_;
};
class GameObject {
public:
void set_texture(const Texture& texture)
{ texture_ = std::unique_ptr<Texture>(new Texture(texture)); }
private:
std::unique_ptr<Texture> texture_;
};
My understanding of this, however, is that a new texture would be copy-constructed from the passed reference, which would then be owned by the unique_ptr. This strikes me as highly undesirable, since I would have as many copies of the texture as game objects that use it -- defeating the point of pointers (no pun intended).
Store not the textures directly, but their shared pointers in a container. Use make_shared to initialize the shared pointers. Construct weak pointers in the game objects.
class TextureManager {
public:
const std::shared_ptr<Texture>& texture(const std::string& key) const
{ return textures_.at(key); }
private:
std::unordered_map<std::string, std::shared_ptr<Texture>> textures_;
};
class GameObject {
public:
void set_texture(const std::shared_ptr<Texture>& texture)
{ texture_ = texture; }
private:
std::weak_ptr<Texture> texture_;
};
Unlike the unique_ptr case, I won't have to copy-construct the textures themselves, but rendering the game objects is expensive since I would have to lock the weak_ptr each time (as complex as copy-constructing a new shared_ptr).
So to summarize, my understanding is such: if I were to use unique pointers, I would have to copy-construct the textures; alternatively, if I were to use shared and weak pointers, I would have to essentially copy-construct the shared pointers each time a game object is to be drawn.
I understand that smart pointers are inherently going to be more complex than raw pointers and so I'm bound to have to take a loss somewhere, but both of these costs seem higher than perhaps they should be.
Could anybody point me in the correct direction?
Sorry for the long read, and thanks for your time!
Even in C++11, raw pointers are still perfectly valid as non-owning references to objects. In your case, you're saying "Let's assume the textures are guaranteed to outlive their pointers." Which means you're perfectly safe to use raw pointers to the textures in the game objects. Inside the texture manager, store the textures either automatically (in a container which guarantees constant location in memory), or in a container of unique_ptrs.
If the outlive-the-pointer guarantee was not valid, it would make sense to store the textures in shared_ptr in the manager and use either shared_ptrs or weak_ptrs in the game objects, depending on the ownership semantics of the game objects with regards to the textures. You could even reverse that - store shared_ptrs in the objects and weak_ptrs in the manager. That way, the manager would serve as a cache - if a texture is requested and its weak_ptr is still valid, it will give out a copy of it. Otherwise, it will load the texture, give out a shared_ptr and keep a weak_ptr.
To summarize your use case:
*) Objects are guaranteed to outlive their users
*) Objects, once created, are not modified (I think this is implied by your code)
*) Objects are reference-able by name and guaranteed to exist for any name your app will ask for (I'm extrapolating -- I'll deal below with what to do if this is not true.)
This is a delightful use case. You can use value semantics for textures throughout your application! This has the advantages of great performance and being easy to reason about.
One way to do this is have your TextureManager return a Texture const*. Consider:
using TextureRef = Texture const*;
...
TextureRef TextureManager::texture(const std::string& key) const;
Because the underling Texture object has the lifetime of your application, is never modified, and always exists (your pointer is never nullptr) you can just treat your TextureRef as simple value. You can pass them, return them, compare them, and make containers of them. They are very easy to reason about and very efficient to work on.
The annoyance here is that you have value semantics (which is good), but pointer syntax (which can be confusing for a type with value semantics). In other words, to access a member of your Texture class you need to do something like this:
TextureRef t{texture_manager.texture("grass")};
// You can treat t as a value. You can pass it, return it, compare it,
// or put it in a container.
// But you use it like a pointer.
double aspect_ratio{t->get_aspect_ratio()};
One way to deal with this is to use something like the pimpl idiom and create a class that is nothing more than a wrapper to a pointer to a texture implementation. This is a bit more work because you'll end up creating an API (member functions) for your texture wrapper class that forward to your implementation class's API. But the advantage is that you have a texture class with both value semantics and value syntax.
struct Texture
{
Texture(std::string const& texture_name):
pimpl_{texture_manager.texture(texture_name)}
{
// Either
assert(pimpl_);
// or
if (not pimpl_) {throw /*an appropriate exception */;}
// or do nothing if TextureManager::texture() throws when name not found.
}
...
double get_aspect_ratio() const {return pimpl_->get_aspect_ratio();}
...
private:
TextureImpl const* pimpl_; // invariant: != nullptr
};
...
Texture t{"grass"};
// t has both value semantics and value syntax.
// Treat it just like int (if int had member functions)
// or like std::string (except lighter weight for copying).
double aspect_ratio{t.get_aspect_ratio()};
I've assumed that in the context of your game, you'll never ask for a texture that isn't guaranteed to exist. If that is the case, then you can just assert that the name exists. But if that isn't the case, then you need to decide how to handle that situation. My recommendation would be to make it an invariant of your wrapper class that the pointer can't be nullptr. This means that you throw from the constructor if the texture doesn't exist. That means you handle the problem when you try to create the Texture, rather than to have to check for a null pointer every single time you call a member of your wrapper class.
In answer to your original question, smart pointers are valuable to lifetime management and aren't particularly useful if all you need is to pass around references to object whose lifetime is guaranteed to outlast the pointer.
You could have a std::map of std::unique_ptrs where the textures are stored. You could then write a get method that returns a reference to a texture by name. That way if each model knows the name of its texture(which it should) you can simple pass the name into the get method and retrieve a reference from the map.
class TextureManager
{
public:
Texture& get_texture(const std::string& key) const
{ return *textures_.at(key); }
private:
std::unordered_map<std::string, std::unique_ptr<Texture>> textures_;
};
You could then just use a Texture in the game object class as opposed to a Texture*, weak_ptr etc.
This way texture manager can act like a cache, the get method can be re-written to search for the texture and if found return it from the map, else load it first, move it to the map and then return a ref to it
Before I get going, as I accidentally a novel...
TL;DR Use shared pointers for figuring out responsibility issues, but be very cautious of cyclical relationships. If I were you, I would use a table of shared pointers to store your assets, and everything that needs those shared pointers should also use a shared pointer. This eliminates the overhead of weak pointers for reading (as that overhead in game is like creating a new smart pointer 60 times a second per object). It's also the approach my team and I took, and it was super effective. You also say your textures are guaranteed to outlive the objects, so your objects cannot delete the textures if they use shared pointers.
If I could throw my 2 cents in, I'd like to tell you about an almost identical foray I took with smart pointers in my own video game; both the good and the bad.
This game's code takes an almost identical approach to your solution #2: A table filled with smart-pointers to bitmaps.
We had some differences though; we had decided to split our table of bitmaps into 2 pieces: one for "urgent" bitmaps, and one for "facile" bitmaps. Urgent bitmaps are bitmaps that are constantly loaded into memory, and would be used in the middle of battle, where we needed the animation NOW and didn't want to go to the hard disk, which had a very noticeable stutter. The facile table was a table of strings of file paths to the bitmaps on the hdd. These would be large bitmaps loaded at the beginning of a relatively long section of
gameplay; like your character's walking animation, or the background image.
Using raw pointers here has some problems, specifically ownership. See, our assets table had a Bitmap *find_image(string image_name) function. This function would first search the urgent table for the entry matching image_name. If found, great! Return a bitmap pointer. If not found, search the facile table. If we find a path matching your image name, create the bitmap, then return that pointer.
The class to use this the most was definitely our Animation class. Here's the ownership problem: when should an animation delete its bitmap? If it came from the facile table then there's no problem; that bitmap was created specifically for you. It's your duty to delete it!
However, if your bitmap came from the urgent table, you could not delete it, as doing so would prevent others from using it, and your program goes down like E.T. the game, and your sales follow suit.
Without smart pointers, the only solution here is to have the Animation class clone its bitmaps no matter what. This allows for safe deletion, but kills the speed of the program. Weren't these image supposed to be time sensitive?
However, if the assets class were to return a shared_ptr<Bitmap>, then you have nothing to worry about. Our assets table was static you see, so those pointers were lasting until the end of the program no matter what. We changed our function to be shared_ptr<Bitmap> find_image (string image_name), and never had to clone a bitmap again. If the bitmap came from the facile table, then that smart pointer was the only one of its kind, and was deleted with the animation. If it was an urgent bitmap, then the table still held a reference upon Animation destruction, and the data was preserved.
That's the happy part, here's the ugly part.
I've found shared and unique pointers to be great, but they definitely have their caveats. The largest one for me is not having explicit control over when your data gets deleted. Shared pointers saved our asset lookup, but killed the rest of the game on implementation.
See, we had a memory leak, and thought "we should use smart pointers everywhere!". Huge mistake.
Our game had GameObjects, which were controlled by an Environment. Each environment had a vector of GameObject *'s, and each object had a pointer to its environment.
You should see where I'm going with this.
Objects had methods to "eject" themselves from their environment. This would be in case they needed to move to a new area, or maybe teleport, or phase through other objects.
If the environment was the only reference holder to the object, then your object couldn't leave the environment without getting deleted. This happens commonly when creating projectiles, especially teleporting projectiles.
Objects also were deleting their environment, at least if they were the last ones to leave it. The environment for most game states was a concrete object as well. WE WERE CALLING DELETE ON THE STACK! Yeah we were amateurs, sue us.
In my experience, use unique_pointers when you're too lazy to call delete and only one thing will ever own your object, use shared_pointers when you want multiple objects to point to one thing, but can't decide who has to delete it, and be very wary of cyclical relationships with shared_pointers.

How to work around a getter that also sets a member?

I'm dealing with something that goes along these lines:
I have a class that is quite complex and a member that depends on some stuff that isn't set when the class is initialized, or is set on the go. Objects of that class make sense even when that member isn't set. It can also be reset depending on other changes that are made to other members.
Now, assume this "special" member is computationally-expensive to set, and so I'm delaying computing it on request.
So:
class Class
{
X x;
Y y;
SpecialClass specialObject;
public:
void setX(const X& newX);
void setY(const Y& newY);
//----
SpecialClass getSpecialObject() /*const*/
{
computeSpecialObject();
return specialObject();
}
private:
void computeSpecialObject()
{
//specialObject depends on x and y
//and is expensive to compute
//this method is a bottleneck
}
};
I don't want to call the compute method every time I change x or y because it's expensive, so I'm left with the dilemma:
remove the const? Logically, the getter should be const, but it can't. There's also the downside that it can't be called on const objects.
I can make specialObject mutable, but it doesn't seem like the right thing to do.
cast away constness? Again, looks fishy.
call computeSpecialObject before the get? - what if someone forgets? They'll get an out-dated result.
Is there a design pattern that deals with this? A good approach? Or is the class design just wrong? (I'd lean towards this last one, but changing the class isn't really an option)
Note: I've made the member mutable, want to know if there's a better solution.
I can make specialObject mutable, but it doesn't seem like the right thing to do.
Why so? That's exactly why mutable exists: to allow a const function to be logically const without the need to physically leave the object unchanged (and if you make the object mutable, remember about ensuring thread-safety - I'm sure you know what I mean).
This is true as long as the initialization of the SpecialClass object is not something that alters the logical state of the object, of course, because that's what const promises not to do.
In that case, the function itself is simply not const in nature, and it should likely be named something different than just getSpecialObject(): computeAndReturnSpecialObject() could be a candidate.
I'd leave the const and either make specialObject mutable or keep a pointer to the specialObject instead of just 'embedding' it into the class.
I would also add a bool dirty flag that is mutable and set it whenever a change is made that invalidates the computation. I would then check the flag inside computeSpecialObject and do the work only if it's set. Using a pointer, you could even delete the old computation object whenever a change invalidates an existing computation, but that opens a whole 'nother can of worms.
Or am I missing something?
It's always a fine line this one, not calling it when you don't need to, versus introduces holes in caller, that mean it might not have been and returning incorrect results.
Me I'd move compute to be method of special object and the treat this class as a wrapper for the arguments for the compute method that class. A bonus ball is you can unit test the computation.
Then it's just a question of deciding when you need to call SpecialObject.Compute(x,y) again or simply return the last result.
Another thing I might look at if I could, would be if X has changed but Y hasn't can I simplify the calculation. i.e. keep some intermediate results.
Not sure how applicable it is for you, but one of the things I regularly end up doing is injecting a something that does the compute, so I tend to fall into this pattern by default.
There are two directions you could go, more OOP or more Functional. One involves caring less about state manipulation, but rather behaviour, the other completely forgets about behaviour, and cares about returned state.
OOP
For me a key OOP principle is Tell, Don't Ask, or write no getters or setters.
Design your objects to be told what to do, to be autonomous. Don't ask it to return some object which you can then use to do something. Just tell it to do the thing you want in the first place. If you're telling an object to do something then you likely expect it to change state, and it's not right for it to be const.
Your SpecialClass may provide some service doService(). You can instead tell Class to doSpecialService(), which is rightly mutable.
An alternative is for the creation of this object to use some other object to do the creation. So a function can be const but take a non const parameter:
class Class {
public:
void doService(ServiceProvider& serviceProvider) const {
serviceProvider.doService(x, y);
}
};
With this you would pass in a SpecialServiceProvider& which would create the correct SpecialClass for the given X and Y. It would be mutable. It would seem correct to modify state in the provision of the service. Maybe you could have a map caching SpecialClass objects for (X, Y) pairs.
Functional
The other direction is to make your objects immutable. Whenever you want some new state create it using the old state as a basis. This could have a knock on effect until you have turtles (almost) all the way down:
class SpecialBuilder {
public:
SpecialBuilder withX(const X& newX) const;
SpecialBuilder withY(const Y& newY) const;
SpecialClass build() const;
};
SpecialBuilder specialBuilder;
SpecialClass special = specialBuilder.withX(x).withY(y).build();
You can share data between each returned SpecialBuilder as it is immutable.

C++ Game State System

Okay: I'm fairly new to C++ and static languages on a whole. Coming from years of ruby (and other dynamic languages) I don't know if this is possible.
I've been making a game state system for... well a game. I want to make the system easy for me to cut and paste into other games without any (or very few) changes.
The two things I am wanting to improve are the way in which states switch and the way in which state pointers are held.
There could be any number of states, but there will always be at least 2 to 3 states active in memory.
Ugliness No 1.
Currently I have a state manager class with something like this in it:
void StateManager::changeState(StateID nextStateID)
{
// UNFOCUS THE CURRENT STATE //
if (currentState())
{
currentState()->onUnFocus();
// DESTROY THE STATE IF IT WANTS IT //
if(currentState()->isDestroyedOnUnFocus()) {
destroyCurrentState();
}
}
if (m_GameStates[nextStateID]) {
// SWITCH TO NEXT STATE //
setCurrentState(nextStateID);
}
else
{
// CREATE NEW STATE //
switch (nextStateID)
{
case MainMenuStateID:
m_GameStates[MainMenuStateID] = new MainMenuState;
break;
case GameStateID:
m_GameStates[MainMenuStateID] = new GameStates;
break;
};
setCurrentState(nextStateID);
}
// FOCUS NEXT STATE //
currentState()->onFocus();
}
This approach works but I don't feel it's very nice.
Is it possible to pass a type? And then call new on it?
new NextGameState; // Whatever type that may be.
Can poloymophism help here? All States are derived from a class State.
Ugliness No 2.
Another thing I think needs some improvement is the way I've been storing the states.
State* m_GameStates[MaxNumberOfStates];
All the states are initialized to NULL, so I can test if a state is there, and if not it creates one when needed.
It works well as I can call the current state:
m_GameStates[m_CurrentState];
However, I don't like this for two reasons. It seems a bit of a waste having an array full of NULL pointers when there will only be 2 or 3 pointers active at any one time. [Editor's note: what is the second reason?]
I thought about shifting this into a vector_ptr, but didn't as it would create extra complications with checking to see if a state exists. And the vector seems to reinforce Ugliness No 1. as I need to have a list to check each state.
Any advice or direction appreciated.
Thanks,
Phil.
Use a enum(eration) to define all possible states (its something like a list with constants).
Just create for one object one variable that holds the state and change the variable whenever you need to change it.
As soon as you say States, I think of the State pattern.
Basically, you can derive a bunch of objects from a State base class. All actions related to a state occur against the current state maintained by the state manager. States will move from state to state via the manager.
For instance, you can have a Paused and Unpaused state, each with a buttonPressed event. When you press a button, the current state is delivered the event. If it's in Paused, and the button was the pause button, move to Unpaused. Vice versa for Unpaused.
void StateManager::changeState(StateID nextStateID)
{
leaveState(actualState);
enterState(nextStateID);
}
I really like this one - as easy as it could be. ;-)
What I want to tell you - I think doing creation/deleting your stats in the changeState Function is too much of logic in there - it just is supposed to change the state, right?
Edit:
To come to your 2 question - I don't think using this array is really a waste - you are talking about 3 fields, not 300 or so. So if you like using arrays - go for it. If you don't, the map would be my choose, it makes things easy if you want to check if there is a state created or not and you are not limited to a magic number "maxStates". You could possible check if there is enough ram and then create X states, not fixed 2-3.
For generating states you want a factory. That way the state id stays nice an generic. For storing states I would go with a std::map
For your first problem, yes, you can pass in a type, with some caveats.
I've added a comment under your question, asking for a bit more information. Until we get that, I can't really say how it should be done, but read up on templates.
You can make a function template, which can be passed a type, for example like this:
template <typename T>
void Foo() {
T* x = new T();
...
}
Foo<int>() // call Foo with the type T set to 'int'
There are some limitations to this, as the types have to be specified at compile-time, but it is a very powerful language feature.
Another option, which might work better since you seem to have an association between a variable (MainState) and a type (MainMenu), might be the use of traits classes. Again, I'm unsure of exactly how it'd be done in your case, since we haven't seen the entirety of the function (in particular, what type is MainState, and how/when is it created?)
It might also be possible to solve the problem through polymorphism, but again, I'd need to see a bit more of the context to suggest a solution.
For your second problem, you can use the standard library map:
#include <map>
// I'm not sure what type m_CurrentState is, so use its type instead of KeyType below
std::map<KeyType, State*> m_GameStates;
// and to perform a lookup in the map:
GameStates[m_CurrentState];
Finally, a really really important bit of advice:
Stop using pointers everywhere. Stop calling new to create new objects.
As a general rule, objects should be created on the stack (Instead of Foo* f = new Foo;, just do Foo f;
And instead of using pointers, you'll often want to just copy the object itself. Alternatively, create references instead of pointers.
And when you do need to use dynamic memory allocations, you still shouldn't use new directly. Instead, create a wrapper object, which internally allocates what it needs with new in its constructor, and frees it again in the destructor.
If you do this correctly, it pretty much solves all the headaches of memory management.
The general technique is called RAII.
Take a look at Boost Statechart Library