Question

If I have a class Rectangle

class Rectangle{

private:
    double width;
    double height;


public:
void    Set(double w , double l){
    width   = w;
    height  = l;
}
};

and I decleare an object such:

Rectangle *Obj;

and then try to initialize its properties:

Obj->Set(3,5);

the compiler shows at run-time: The variable 'Obj' is being used without being initialized.

The problem can be solved by:

Rectangle *Obj=new Rectangle;

I would ask about the reason! And why the compiler doesn't show any error at compiling time?

Was it helpful?

Solution

Rectangle *Obj;

just defines a pointer to an object of class Rectangle. Defining a pointer does not reserve any memory for the object itself, just for the pointer. Thus, if you access the pointer, you will likely end up at an address in memory that doesn't even belong to your process. However, the compiler cannot know that you haven't initialized the pointer (the keyword here is aliasing) and hence cannot output an error message.

The solution is either using new like you suggested, or declare an instance of Rectangle like so:

Rectangle Obj;

which will call a default constructor. You can then set your members using

Obj.Set(3, 5);

OTHER TIPS

and I decleare an object such:

Rectangle *Obj;

Wrong, this declares a pointer, not an object. Pointers have to be initialized either using new or by assigning them the address of an existing object.

Mmm a bit of confusion there:

the compiler shows at run-time: The variable 'Obj' is being used without being initialized

That is what you'd call compile time. Just straightening out the jargon.

Also, the simplest way would be to

Rectangle Obj;
Obj.Set(3,5);

which is sufficient for most scenarios, except dynamic allocations, or polymorphic containers:

std::vector<Shape*> v;
v.push_back(new Rectange());
v.back()->Set(3,5);

v.push_back(new Circle());
v.back()->Set(3,5);

//

Although whenever using new you should be remembering to delete as well. This can be quite a nightmare (in the light of exceptions, too). I suggest:

std::vector<std::shared_ptr<Shape*> > v;
v.push_back(std::make_shared<Rectange>());
v.back()->Set(3,5);

v.push_back(std::make_shared<Circle>());
v.back()->Set(3,5);

With Rectangle *Obj;, you are declaring a pointer to a Rectangle, but you haven't told Obj to which Rectangle it should point. You might set or instantiate Obj later on to an existing Rectangle or only if you require.

C++ is all about giving you precise control over your memory and performance. In fact, that's why it is used in some embedded environments! Automatically instantiating Obj poses several "issues"

  • When do we free Obj?
  • Who frees Obj?
  • What about the performance implications of creating a Rectangle on the heap?
  • Is this an environment in which we have enough resources (memory, CPU, etc) to even create the Rectangle, especially if it is large.
  • Do you pass the address of Obj somewhere and then instantiate it at runtime through some complex method that we can't statically analyse?

What you do isn't a syntax error, which is what compilers throw errors on -- errors when compiling. An analyser (one is built into Visual Studio 2010 professional) might warn you that you're using an uninitialized variable, though that is optional and you may need to turn it on.

pointer without new is declaring something without memory .. SO u have to use new with pointer. However Rectangle rect; will defaultly allocate the memory .

to check this, make a constructor in Rectangle class like,

void Rectangle
{
  cout<<"Rectangle Constructor";
}

then,in main

Rectangle *rect; -->>O/P  -- "Nothing"
Rectangle rect2; -->>O/P  -- Rectangle Constructor
rect=new Rectangle; -->>O/P  -- Rectangle Constructor

why the compiler doesn't show any error at compiling time?

Because, it's syntactically correct. However, such statements will lead to undefined behavior, smart compilers will always issue warning.

In g++ you can turn such kind of compiler warning in errors.

The statement rectangle *obj just means that there exist a pointer, that will point to the variable of type rectangle.

With this statement you are just creating a pointer not the instance of the object rectangle for the usage of this pointer you must store the rectangle type variable's address in the pointer

The two ways of doing it are by

obj=new rectangle;  //variable is created in the stack storage

or

rectangle r;
obj =&r;     //variable is created in the heap storage
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top