The Difference Between These Two Statements

I come from a C#/VB.NET background and I'm a little confused about these two statements:

player would be declared as a public class.

1
2
3
4
5
6
7
8
9
10
void somemethod()
{
    //as far as I know this calls the default constructor
    player p;

    //this is also calling the default constructor but
    //I'm creating a pointer to this object
    player * p2 = new player;

}


What is the difference between these statements? Does the variable 'p' go out of scope at the end of the method whereas 'p2' will stay until I assign it a null pointer? Does that mean I need to code for 'p2' to be released? And I don't for 'p'? Which statement is the proper one to use?

Sorry for so many questions.

Thanks

p has automatic storage. It will be destructed when the block it was declared in ends.
The thing p2 points to will remain there even if p2 itself goes out of scope or is assigned something else.
1
2
3
4
5
6
7
8
9
10
11
    player *p2 = new player;
    //p2 now points to an object, which I'll call A.
    delete p2;
    //A no longer exists and p2 points to invalid memory.
    p2 = new player;
    //p2 now points to B.
    p2 = new player;
    //p2 now points to C.
    //Whoops! B is now unreachable. It's a memory leak.
}
//Whoops again! Now C is unreachable, too. 


Which statement is the proper one to use?
It depends on what you're trying to do. Automatic storage tends to produce fewer memory management bugs, but it's less versatile than dynamic allocation. For example, you can't return such an object from a function without making a copy.
Can you please tell me the proper way I should be releasing/deleting objects in this example?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "stdafx.h"

class player
{
public:
	char * name;
};

class state
{
public:
	player *player1;
public:
	player *player2;

	void initialize()
	{
		this->player1 = new player();
		this->player2 = new player();
	}
};

int _tmain(int argc, _TCHAR* argv[])
{
	//first state object, automatic
	state gs;
	gs.initialize();

	//second state object, dynamic
	state *gs2 = new state();
	gs2->initialize();

	return 0;
}


Would I create destructors on each type and call them? Do I use the delete key word? And does this example even make sense? Like, would anyone ever do it this way?
Last edited on
In this case, it'd be best for player1 and player2 to be objects, rather than pointers.
Use constructors instead of initialize()-like member functions.
Err... I'm confused. I thought I was creating objects... Am I not calling the constructors when I go "new player()"?

objects, rather than pointers.


What does that mean? Don't I create the object and then "save" the pointer?

Also, what do I do about the name variable?
Last edited on
Alright, maybe this is what you mean?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "stdafx.h"

class player
{
public:
	char * name;

	~player()
	{
		this->name = NULL;
	}
};

class state
{
public:
	player player1;
public:
	player player2;

};

int _tmain(int argc, _TCHAR* argv[])
{
	//first state object, automatic
	state gs;

	gs.player1.name = "First";
	gs.player2.name = "Name";

	return 0;
}


This is safe from memory leaks correct?
Last edited on
Yes, although your grasp of strings is not quite right. Not to worry. You'll get it eventually.
Haha, yes I am used to very flexible-compiler-takes-care-of-everything coding. What should I be doing for the strings? To me char * is a pointer to 1 character, so I don't actually know how that code is even working. I would think it would have to be char[] * or something.
In C and C++, there's no difference between a pointer to one object (here I'm using the word "object" to refer to both OOP objects and things such as integers) and a pointer to an array of objects. It's up to the programmer to encode that information into the program; for example, by not trying to iterate over a single object. But you'll typically only use arrays when you want a buffer for binary data, and you'll instead use vectors to store collections of objects, so don't worry too much about it. Just be aware that a char * can point to a single char or to an array of chars.

As for strings, for the time being just use the std::string class, which behaves the most like the strings you're used to.
That was really insightful, thank you very much helios.
Topic archived. No new replies allowed.