Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

New to pointers


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 Jebbs   Members   -  Reputation: 234

Like
0Likes
Like

Posted 05 August 2012 - 04:33 PM

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?

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;
		}
}

Edited by Jebbles, 05 August 2012 - 04:35 PM.


Sponsor:

#2 Aardvajk   Members   -  Reputation: 2408

Like
0Likes
Like

Posted 05 August 2012 - 04:41 PM

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.

#3 NightCreature83   Crossbones+   -  Reputation: 1173

Like
0Likes
Like

Posted 05 August 2012 - 06:13 PM

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.

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 shallow copy 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 deep copy

Edited by NightCreature83, 05 August 2012 - 06:18 PM.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2

#4 Aardvajk   Members   -  Reputation: 2408

Like
0Likes
Like

Posted 06 August 2012 - 04:13 PM

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 shallow copy 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 deep copy


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.

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));
}


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

Edited by Aardvajk, 06 August 2012 - 04:14 PM.


#5 NightCreature83   Crossbones+   -  Reputation: 1173

Like
0Likes
Like

Posted 07 August 2012 - 01:16 AM

Isn't it just a warning you are getting about z not being inialised as MSVC2010 compiles that code fine.
Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2

#6 Aardvajk   Members   -  Reputation: 2408

Like
0Likes
Like

Posted 07 August 2012 - 01:42 AM

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.

#7 SiCrane   Moderators   -  Reputation: 6663

Like
1Likes
Like

Posted 07 August 2012 - 02:10 AM

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:
void f() {
    int z;

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

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

#8 Aardvajk   Members   -  Reputation: 2408

Like
0Likes
Like

Posted 07 August 2012 - 01:17 PM

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.


Interesting, thanks SiCrane.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS