views:

183

answers:

6

can anyone tell me whats the difference between

Display *disp = new Display();

and

Display *disp;
disp = new Display();

and

Display*  disp = new Display();

and

Display*  disp(new Display());

Regards,
Zeeshan

Also, i am very new to c++, just trying to figure out a few things. If you thing my questions are smelly, let me know. I will stop asking anything else here.

A: 

One creates an object of type Display and one of the type GzDisplay, is this on purpose or is it a typo?

If it's a typo then there's no difference in regards to the code generated but the first method is preferred since there is no time in which the variable disp is in scope and uninitialized.

Motti
A: 

1) Instance of GzDisplay is created in 2nd variant, whereas in 1st variant, created instance is of Display type (I assume GzDisplay is subclass of Display, right?); 2) Besides that 1st is shorter, in 2nd disp have undefined value until assigned with new GzDisplay(). 2nd variant gives you a chance to accidentally forget that and insert some code that uses disp before it initialized.

Victor Sorokin
+3  A: 

The first case:

Display *disp = new Display();

Does three things:

  1. It creates a new variable disp, with the type Display*, that is, a pointer to an object of type Display, and then
  2. It allocates a new Display object on the heap, and
  3. It sets the disp variable to point to the new Display object.

In the second case:

Display *disp; disp = new GzDisplay();

You create a variable disp with type Display*, and then create an object of a different type, GzDisplay, on the heap, and assign its pointer to the disp variable.

This will only work if GzDisplay is a subclass of Display. In this case, it looks like an example of polymorphism.

Also, to address your comment, there is no difference between the declarations:

Display* disp;

and

Display *disp;

However, because of the way C type rules work, there is a difference between:

Display *disp1;
Display* disp2;

and

Display *disp1, disp2;

Because in that last case disp1 is a pointer to a Display object, probably allocated on the heap, while disp2 is an actual object, probably allocated on the stack. That is, while the pointer is arguably part of the type, the parser will associate it with the variable instead.

Daniel Pryden
He's changed the question. GzDisplay no longer exists.
Vulcan Eager
@Daniel: I think you're confused; SO only displays the author of the most recent edit; you have to click on the "17 minutes ago" (or whatever time its displaying for you) to see all the revisions, and who made them. When you do that, you'll discover that the original poster changed the question. Comment at meta.stackoverflow.com if you feel the UI is confusing.
derobert
@derobert: My apologies. I've removed my comments.
Daniel Pryden
+1  A: 
Display *disp = new Display();

This line of code create a variable of type Display* and initializes it with the address of a newly created object.

Display *disp;        // (1)
disp = new Display(); // (2)

First line of code simply declares a variable of type Display*. Depending on your compiler settings - the pointer may or may not be initialized. Basically, it should be treated as an invalid pointer, that doesn't necessary point to NULL.

Second line assigns address of a newly created object to the pointer.

The outcome of both code snippets will be the same.

With optimizations enabled, any compiler should generate the same assembly for both of them. With optimizations disabled, and with some debug code generation - both snippets might generate totally different code - in the second case, the pointer would first be initialized with a value used by compiler for uninitialized pointers (something like 0xDEADBEEF, or 0xEFEFEFEF - and easily recognizable pattern). In the first snippet - the pointer should always be initialized to the address of the object, regardless of the settings. Note, that this is compiler-dependent - some compilers might do as I say, some may do somthing completely different.

Paulius Maruška
A: 

You have found four ways to write the same thing.

Examples 1 (Display *disp…) and 3 (Display* disp…) are identical; the spacing around * does not matter. However, style 1 is often preferred, because:

Display* disp1, disp2;

actually means:

Display *disp1, disp2;

i.e., disp2 is not a pointer.

Example two (splitting across two lines) has the same effect, and will probably be compiled to the same code. The fourth example, using initializer syntax, does the same thing as well.

Note that if these were classes, not pointers, there could be a difference in behavior and speed.

derobert
@Daniel: I did no such thing. http://stackoverflow.com/revisions/1371608/list, revision 4, shows the OP changes his own question. I just fixed his formatting for him.
derobert
@derobert: Retracted, my apologies. As I don't have enough rep yet to edit others' questions, I wasn't aware of how to search the previous revisions of a question. I've also removed my downvote.
Daniel Pryden
+4  A: 
// implicit form
// 1) creates Display instance on the heap (allocates memory and call constructor with no arguments)
// 2) creates disp variable on the stack initialized with pointer to Display's instance
Display *disp = new Display();

// explicit form
// 1) creates Display instance on the heap (allocates memory and call constructor with no arguments)
// 2) creates disp variable on the stack initialized with pointer to Display's instance
Display* disp(new Display());

// 1) creates uninitialized disp variable on the stack
// 2) creates Display instance on the heap (allocates memory and call constructor with no arguments)
// 3) assigns disp with pointer to Display's instance
Display *disp;
disp = new Display();

Difference between explicit and implicit forms of initialization will be seen only for complex types with constructors. For pointer type (Display*) there is no difference.

To see the difference between explicit and implicit forms check out the following sample:

#include <iostream>

class sss
{
public:
  explicit sss( int ) { std::cout << "int" << std::endl; };
  sss( double ) { std::cout << "double" << std::endl; };
  // Do not write such classes. It is here only for teaching purposes.
};

int main()
{
 sss ddd( 7 ); // prints int
 sss xxx = 7;  // prints double, because constructor with int is not accessible in implicit form

 return 0;
}
Kirill V. Lyadvinsky