Society of Robots - Robot Forum

Software => Software => Topic started by: mstacho on March 20, 2014, 06:56:10 AM

Title: OOP question
Post by: mstacho on March 20, 2014, 06:56:10 AM
Alright, this one is going to be weird.  I"m making up a tutorial for first year students and I got this question, and I have no idea why it works :-P

Question: why does the following code work?

First, assume I've made a class like this in, say, C# or Java:

Code: [Select]
class myClass
{
      public int x;
      public myClass()
      {
          this.x = 4;
       }
}

Then, I make another class with a main function:

Code: [Select]
main()
{
     myClass x = new myClass();
}

I've made a new instance of myClass called x despite the fact that myClass has a variable x.  I know you CAN do it (you shouldn't...) but why?  is it the namespaces or scope or something?

Mike
Title: Re: OOP question
Post by: jwatte on March 20, 2014, 03:07:55 PM
You have not made another "class," you have made another "object" which is an instance of a class.

Think of classes as "stencils" or "blueprints," and instances as "paintings" or "houses that are built."

And yes, the two "x"-es are independent, because the scope of the first is methods-of-myClass, whereas the scope of the second is the-function-main. Because the-function-main is not a method-of-myClass, there is no ambiguity.
Title: Re: OOP question
Post by: Webbot on March 24, 2014, 03:54:49 PM
is it the namespaces or scope or something?

Its kinda both.
in your 'main' the variable 'myClass x' has a scope that says it only exists in 'main' - once 'main' exits then it is thrown away. Since this is just a standard C++ variable then it is in the default namespace ie its fully qualified name is '::x'.

imagine if you had a global variable 'int x;' then it also has a qualified name of '::x'.

So inside 'main' it looks at the scope and references to '::x' would use the first variable defined in main, but outside of 'main' it would reference the global variable.

Inside your class there is a variable with a namespace 'myClass' called 'x' - so think of its fully qualified name as 'myClass::x'. Since its qualified name is different to '::x' then they are different variables. But to access one of these variables then it needs to know what the current instance of the myClass to use to get the variable x - each instance of myClass has its own. Within side code of the myClass then any references to 'x' will address the variable for this instance. Outside of your myClass code then you need to say which instance of myClass to use to get the x variable from.

Know that a class is really just like a C 'struct' definition and that an instance is like the usage of the struct.
ie assume you want to store data about a rectangle. Then in C you would have:-
Code: [Select]
// Define a data structure that can hold the info
struct s_rectangle {
     int x,y,width,height;
}
The above generates NO code - it is just defining a new datatype. C has simple types types like int, unsigned etc etc but the above just creates a more complex type made up of many parts that are referenced by name.

To create two instances of rectangles we could in C:
Code: [Select]
struct s_rectangle rectangle1 = {0,0, 100, 120};
struct s_rectangle rectangle2  = {0,10, 150, 80};

Now lets say we need a function to return the area of the rectangle we could have a function:-
Code: [Select]
long calcArea(struct s_rectangle* this){
   return this->width * this->height;
}
See how that function needs to be passed a reference to the rectangle to use to get the individual fields from. It could be called via
Code: [Select]
long area = calcArea(&rectangle1); // get area for rectangle 1

To convert to C++ then create a class rather than a struct (although they are really the same thing!)
Code: [Select]
class Rectangle {
public:
  Rectangle(int rx,ry,rw,rh){
     // copy parameters to local vars
     x = rx; y=ry; width=rw; height=rh;
  }

  long calcArea(){  // Think of c++ method as having a hidden parameter called 'this'
   return width * height;  // Is like doing this->width * this->height in C
  }

private:
  int x,y,width,height;   // Just like the struct !
};

Quote
I know you CAN do it (you shouldn't...)
Not really true and in a large system almost impossible to avoid. Read up on 'encapsulation'.