Jump to content
  • Advertisement
Sign in to follow this  
Sean_Seanston

How to Best Implement Objects with "Optional" Functionality?

This topic is 1180 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a few ideas of how this might be implemented, but because I'm not sure if some ways are obviously better than others and because it could involve pointers, I thought I'd ask...

 

Let's say we have a situation in a game where one object may possess a certain feature or may not. An example that's very close to what I'm actually trying to do would be something like:

- We have a Location class.

- A Location may contain(or reference, w/e) zero or exactly one Safehouse object.

- Depending on whether or not the Location has a Safehouse when the player is interacting with the Location, the game/UI/menu/whatever will display different options to the player.

i.e. Right now I'm working off the assumption that if a Menu should display certain things based on the existence of a Safehouse or not, then the Menu should be able to query somehow whether or not a valid Safehouse actually exists.

 

I can see some different ways of accomplishing this, but I'm not sure which are reasonable and which should be avoided:

 

1. What I would have done in the past, and the first idea to come to me, was to use a simple pointer. I'd point it to a Safehouse if it existed, otherwise it would be set to null, and so the game could check if it was null and know whether or not a valid Safehouse existed in that way.

My problem with this is that I'm afraid of it being bad practice, and of memory leaks where the risk is probably not necessary.

 

2. I could use smart pointers, but I don't currently have a compiler that supports C++11 due to being on Vista, so it would have to be auto_ptr. Does that sound like a potentially good idea in this situation?

 

3. Use a vector. Then if the vector is empty, there are no valid Safehouse objects and there's no fear of trying to call a member function of a null pointer or dealing with pointer allocation/deletion.

My problems with this are that it would seem to complicate matters such as dealing with encapsulation (accessing the elements without it being long-winded), and technically... I know it's not a big problem to just use a container and leave the possibility open of eventually having more than one, but as a learning experience I'm somewhat avoiding the issue.

What IF I definitely only wanted a single object? What would be good practice then?

 

4. Use a static Safehouse object in each Location. Use some sort of flag to denote whether or not it's valid. Seems ugly to me, and wasteful though that probably won't be a practical concern here anyway. Then again, maybe this is the only real solution if I demand a single object only and no pointers?

 

Looking at these, I'm leaning towards 3. Only thing is, something that always trips me up in situations like this: I'm not sure what's good practice for accessing a container outside the containing class.

e.g. Let's say we have a container of purchasable items, and another class needs to display information about these items. Is it best to just have the whole container returned by const reference?

Perhaps we're meant to avoid needing to access a container like this from outside... but then we can't decouple the item data from the user interface code, which to me sounds like it would be more important.

Share this post


Link to post
Share on other sites
Advertisement

2. I could use smart pointers, but I don't currently have a compiler that supports C++11 due to being on Vista, so it would have to be auto_ptr. Does that sound like a potentially good idea in this situation?


Visual Studio 2010 runs on Vista, supports enough of C++11 for smart pointers, and the standard C++11 smart pointers (unique_ptr, shared_ptr, and weak_ptr) are part of 2010's standard library.

Share this post


Link to post
Share on other sites
Go with this and wrap the allocation and deletion of the pointer in your class ctor and dtor which contain the safehouse object.

It's the simplest solution and simple is always best.

 

 

 


wrap the allocation and deletion of the pointer in your class ctor and dtor

 

^^^ This.

Really? Kewl. Maybe I wasn't so naive after all... making sure the destructor deleted the pointer was what I originally had assumed was the right (and only necessary) thing to do.

 

That's encouraging...

 

Visual Studio 2010 runs on Vista, supports enough of C++11 for smart pointers, and the standard C++11 smart pointers (unique_ptr, shared_ptr, and weak_ptr) are part of 2010's standard library.

 

K, that's good to know. I'll have a look at that. Some of the C++11 features look really nice... auto in particular for sheer laziness.

Share this post


Link to post
Share on other sites

 

Go with this and wrap the allocation and deletion of the pointer in your class ctor and dtor which contain the safehouse object.

It's the simplest solution and simple is always best.

 

 

 


wrap the allocation and deletion of the pointer in your class ctor and dtor

 

^^^ This.

Really? Kewl. Maybe I wasn't so naive after all... making sure the destructor deleted the pointer was what I originally had assumed was the right (and only necessary) thing to do.

In which case you will have to make sure you also implement the assignment operator and copy constructor, due to the rule of three.

 

You have to think about lifetime management and ownership. Does the Location own the Safehouse, and determine it's lifetime (a Safehouse cannot exist without a Location), or can a Safehouse exist without a Location? This will determine if you need to allocate the Safehouse object in Location or just supply a pointer from the outside and have the Location reference it without having to care about the lifetime of it.

Share this post


Link to post
Share on other sites

If you're talking C++11, what about the move constructor?

 

Should this be implemented in this case also?

Edited by braindigitalis

Share this post


Link to post
Share on other sites

If you're talking C++11, what about the move constructor?

 

Should this be implemented in this case also?

If you have C++11, then yes, you need to implement move assignment and move constructor due to the rule of five which is just an extension of the Ro3.

 

And you can always try the rule of zero, where you don't implement either of these, let the compiler generate them for you, and handle the lifetime of objects manually through init/shutdown/create/destroy functions. It's much more explicit and requires good programmer discipline with some very specific design choices, but i find it's much nicer to never have to worry whether i'm implementing copy and move semantics correctly or not.

Share this post


Link to post
Share on other sites

That's a very interesting and in-depth explanation... shows why people make such a big deal of pointers.

 

So basically... do it like I was going to with the raw pointer, and just use a smart pointer instead?

 

Think I'll just use Boost then, since I've used some of it in the past and I have it all set up in my project anyway from when I was going to use something that didn't pan out in the end.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!