Sign in to follow this  

New to pointers

This topic is 1952 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

Hey guys!

I'm not new to programming, but it's been many years since I really used C++, and I don't think we even touched on pointers(it was in highschool). Anyways, I have some working code, but since I'm not a pointer expert I wanted to make sure that I was doing this correctly.

Currently, I'm working on a small prototype for a game to kind of help me get some basic ideas down as well as help me get back into the way C++ does things. I'm using SFML and my question really applies to how I have my game screens set up. In each game screen, it holds a pointer to the RenderWindow so that when Draw is called the RenderWindow would not have to be passed before each frame is drawn.

Since the RenderWindow will have its own destructor called all I do is set the pointer to 0. Is that all I really have to do?

Here's some code just to be certain.

This is not all my code, just the code in question. Like I said, I wanted to make sure that I'm doing this correctly. Everything compiles and it runs fine!

tl;dr

Is this an acceptable use of pointers?

[CODE]
class BasicGameScreen
{
private:
//Window used for Rendering
sf::RenderWindow *MainApp;
public:

void Initialize(sf::RenderWindow &App)
{
MainApp = &App;
}

void :Draw()
{

//drawing whatever
MainApp->Draw(Background);
MainApp->Draw(Sprite);
}

~BasicGameScreen()
{
MainApp = 0;
}
}
[/CODE] Edited by Jebbles

Share this post


Link to post
Share on other sites
No problems with that really. You might like to consider passing the MainApp pointer into BasicGameScreen's constructor so you avoid having a BasicGameScreen ever exist without the pointer initialised - as is if you called Draw() before Initialize() by mistake, you'd crash in a nasty way.

The other approach to consider is to pass a reference to MainApp to the Draw() method as a paramter. I generally prefer this when possible as it reduces the amount of bookeeping within classes and makes it easier to re-use a class in the future.

The other option would be to store a reference to MainApp rather than a pointer, initialised again in the constructor but having reference members of classes is a tricky business and can have implications for storing instances of your class in standard containers etc.

Share this post


Link to post
Share on other sites
[quote name='Aardvajk' timestamp='1344206489' post='4966483']
No problems with that really. You might like to consider passing the MainApp pointer into BasicGameScreen's constructor so you avoid having a BasicGameScreen ever exist without the pointer initialised - as is if you called Draw() before Initialize() by mistake, you'd crash in a nasty way.

The other approach to consider is to pass a reference to MainApp to the Draw() method as a paramter. I generally prefer this when possible as it reduces the amount of bookeeping within classes and makes it easier to re-use a class in the future.

The other option would be to store a reference to MainApp rather than a pointer, initialised again in the constructor but having reference members of classes is a tricky business and can have implications for storing instances of your class in standard containers etc.
[/quote]
If in your case MainApp pointer can never be null in a BasicGameScreen instance you need to use a reference as that makes that clear in the semantics of the class. A reference has to be initililased at the time to class instance is created, which means that whatever it aliases needs to exist as long as this class exists.

If you can't guarantee either of these conditions use a pointer. If you can't guarantee condition two and you are using a reference you can get a reference that's pointing at random memory which the runtime will always try to interpret as the definition of the class being referenced.

Having pointer or reference parameters can mean problems with any type of copy construction, that's the problems you face with STL containers anyway. If a [url="http://en.wikipedia.org/wiki/Object_copy#Shallow_copy"]shallow copy[/url] is fine, this is the copy constructor C++ will generate for you, there should be no trouble. However when a shallow copy isn't fine you will have to define your own assignment and copy constructors to do a [url="http://en.wikipedia.org/wiki/Object_copy#Deep_copy"]deep copy[/url] Edited by NightCreature83

Share this post


Link to post
Share on other sites
[quote name='NightCreature83' timestamp='1344211987' post='4966495']
Having pointer or reference parameters can mean problems with any type of copy construction, that's the problems you face with STL containers anyway. If a [url="http://en.wikipedia.org/wiki/Object_copy#Shallow_copy"]shallow copy[/url] is fine, this is the copy constructor C++ will generate for you, there should be no trouble. However when a shallow copy isn't fine you will have to define your own assignment and copy constructors to do a [url="http://en.wikipedia.org/wiki/Object_copy#Deep_copy"]deep copy[/url]
[/quote]

How do you suggest defining a default constructor or an assignment operator for a class containing a reference?

The simple rule of "if it cannot be null, use a pointer" applies to function parameters but cannot be universally applied to class members as well.

[source]
class xxx
{
public:
xxx(int &a) : a(a) { }
xxx(const xxx &b) : a(b.a) { }

int &a;
};

void f()
{
int z;

std::vector<xxx> a;
a.push_back(xxx(z));
}
[/source]

Won't compile (with GCC anyway). A class containing a pointer member can easily be made to work however. Edited by Aardvajk

Share this post


Link to post
Share on other sites
Hmm, checked again, definatly an error from GCC but it is complaining that the default assignment operator is not sufficient, which admittedly seems a bit odd.

Not sure if GCC or VS is correct here as far as standard is concerned. I thought a class containing a reference member was non-copyable but thinking about it now, I'm not sure why.

Share this post


Link to post
Share on other sites
With C++03, in order for a type to be usable in a standard library container, it needs to have both a copy constructor and an assignment operator. With C++11, the situation is a little more complex. Only some of the operations require an assignment operator to be available. Some functions only need the type to be move constructable, copy constructable, etc. Since MSVC 2010 is more or less a C++11 compiler, it doesn't freak out if there's a missing assignment operator where other compilers might complain. If you change your function to:
[code]
void f() {
int z;

std::vector<xxx> a;
a.push_back(xxx(z));

std::vector<xxx> b;
b = a;
}
[/code]
it should start complaining about the container assignment since container assignment requires that assignment of the contained type be allowed.

Share this post


Link to post
Share on other sites
[quote name='SiCrane' timestamp='1344327049' post='4966937']
With C++03, in order for a type to be usable in a standard library container, it needs to have both a copy constructor and an assignment operator. With C++11, the situation is a little more complex. Only some of the operations require an assignment operator to be available. Some functions only need the type to be move constructable, copy constructable, etc. Since MSVC 2010 is more or less a C++11 compiler, it doesn't freak out if there's a missing assignment operator where other compilers might complain.[/quote]

Interesting, thanks SiCrane.

Share this post


Link to post
Share on other sites

This topic is 1952 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this