Welcome~~~


Another blog:
http://fun-st.blogspot.com/

It is easier to write an incorrect program than understand a correct one.

Tuesday, March 1, 2011

Reading Notes from Gilius.org

Please refer to Gillius. org for the original content

Posted some very good illustration of the OOP (http://www.gillius.org/ooptut/part2.htm#A Real Programming Example)

Some notes:
-1- when declare the init() function, we do not put any parameter there. It will be accepted by any compiler, also leave us space to derive its function in a more freely way later. 
-2- Constructors working in inhertance always call the lowest level first, and destructors work in the opposite order, so when BarWindow() is called by the statment "BarWindow my_win;", first Window() is called then BarWindow(). When the object goes out of scope and is destructed, ~BarWindow() is called first then ~Window(). The best way to look at this is with a pyramid -- the base brick is the first brick to be built and the others are layed on top. When you take apart the pyramid the blocks on top come off first. This "pyramid" can be build as high as you need it.
-3- The below framework is good in the sense that with additional init(), we have more choice when define an instance, and is easier to export:

  class Object { public:   Object();   //Set up acceptable defaults, alloc mem   ~Object();  //Deallocate memory if any was reserved
    void Init();//Sends unique data for this instance
    bool Update();//returns true if the object needs to be killed   void Draw();//If graphical, displays itself to user
    void Save(int file);//Pass a file descriptor and save   void Load(int file);//Read Init() info from a file private:   //Object data would go here };
-4- A good way to understand the difference between the ampersand& and asterisk*

pointer should intuitively follow this approach:

  MyClass* classPtr; classPtr = new MyClass();

As with other variables, all of the same rules apply, the ampersand (&) to get the address, and the leading asterisk (*) to reach the actual data.

But what of the dot operator (.)? The dot operator requires data on the left side in order to access a function/variable in the class. You could do it this way:

  (*classPtr).someFunction(); (*classPtr).someVariable = 15;

This statement works, but requires more typing. Luckily there is a shortcut for this, using the indirection operator (->). This operator works on a pointer to a class just like the dot operator. Note that if you use it to access a variable it returns the data of that variable and not a pointer to it:

  classPtr->someFunction(); //Same as statements above classPtr->someVariable = 15;

-5- There are good examples for using "class" to do the "data structure" -- 
          class LinkedList 
-6- Very good explanation of what would happen when Assigning an DervClass to a BaseClass point
In Chapter VI - Virtual Functions: Pointers and Derived Classses 
  class BaseClass { public:   void doStuff();    int data; };
  class DervClass : public BaseClass { public:   void doStuff();    int moreData; };
  void main() {   DervClass obj1;   BaseClass obj2;   BaseClass* ptr1 = &obj1; //Assigning an DervClass to a BaseClass pointer! }

This can seem pretty extreme, but if you think about it, this is totally workable. On a BaseClass*, you can use all of the functions available in BaseClass, which work on BaseClass variables. These functions and variables also exist in DervClass, being a class derived from BaseClass, and so the same things should work. This is because DervClass is really a "BaseClass and then some," and you can always in a sense "downgrade" your status.

When you call methods or access variables from the pointers, everything works as normal except for the fact that when you use the base pointer, you can only access things from the base class. For example, given a continuation of main() from above:

  ptr1->doStuff(); //Calls BaseClass::doStuff(), NOT DervClass:dostuff()! ptr1->moreData = 5; // NOT valid since moreData is in DervClass, and                     //this is a BaseClass* ptr1->data = 10;    //Valid statement

In the next few lessons you will see how to overcome the problem presented by the last code, where the BaseClass::doStuff() was called when you probably wanted to call DervClass::doStuff().

-7- About the virtual function:

The reserved word virtual is the main concept presented by this code. On methods besides the destructor, this means that the method can be overridden by an inherited class when the method is called on the base pointer. This can sound confusing at first since the previous lessons have already shown this is possible. But with virtual functions the point is that you do not need to know which class it came from! Observe the following code:

  //The usual way: Person man("Bob", 35, "15th S Pine St"); Student woman("Jill", 19, "n/a -- dormatory", "RIT"); man.display();   //This is valid, called Person::display() woman.display(); //calls Student::display()  //With virtual methods: Person* baseptr = man; baseptr->display(); //calls Person::display() baseptr = woman;    //Can assign Student* to Person* baseptr->display(); //Calls Student::display();

Using the virtual keyword we overcame the problem we had in the first lesson for this chapter. Even when the pointer loses its identity we can still override functions in the derived class. Note that even still, the method must exist in the base class in order to call it -- it is just simply virtual says it should look to see if there is an override.

-8- About the virtual destructor
with a virtual destructor, if you have a BasePointer  pointing to the DerClass, when call the destructor, it will only call the destructor in the base class, to declare the destructor in the base class to be virtual, the compiler will look further to call the destructor of the Derived Class. 
            
--

♥ ¸¸.•*¨*•♫♪♪♫•*¨*•.¸¸♥

No comments:

Post a Comment