Search This Blog

Tuesday, May 4, 2010

Changing visibility of member function in derived class

Few days back we had discussion in my company regarding "Whether square class should derive from Rectangle class or not?" (Please note this discussion was just part of debate and has nothing to do with source of software I work on)

You can google above question - you will get good amount of papers :). Here is one link

We were talking about the problem that having SetHeight() and SetWidth() methods in square's public interface does not look good.
I though of making these methods private. This looked perfect solution for me (*correction - poor me) for the problem in hand -


=========**=========**=========Code=========**=========**=========
 

#include <iostream>

using namespace std;

class Rectangle {
public:
 Rectangle() {mWidth = 0.0; mHeight = 0.0; }
 virtual void SetHeight (double Height);  // Access specifier is public 
 virtual void SetWidth (double Width);    // Access specifier is public 
 ~Rectangle() {}
protected:
 double mWidth;
 double mHeight;
};

void Rectangle::SetHeight(double Height) {
 mHeight = Height;
}

void Rectangle::SetWidth(double Width) {
 mWidth = Width;
}

class Square : public Rectangle {
public:
 Square() {mWidth = 0.0; mHeight = 0.0; }
 void SetDimension(double Dimension);
 ~Square() {}
private:
 virtual void SetHeight (double Height);   // Access specifier is private 
 virtual void SetWidth (double Width);     // Access specifier is private 
};

void Square::SetDimension(double Dimension) {
 mWidth = mHeight = Dimension;
}

void Square::SetHeight(double Height) {
 mWidth = mHeight = Height;
}

void Square::SetWidth(double Width) {
 mWidth = mHeight = Width;
}

int main () {
 Square mySquare;

 // mySquare.SetWidth(20.0);   // Compilation error - for calling private member
 Rectangle &rect = mySquare;
 rect.SetWidth(20.0);          // SetWidth() is public in Rectangle class :)

 return 0;
}
=========**=========**=========Code=========**=========**=========

As you can see in above code -
1. As expected user can not call SetWidth() on Square object directly.
2. But user can call SetWidth() on Square object indirectly using reference or Pointer
3. As shown in code rect.SetWidth(20.0) calls private function of Square!!
Because - SetWidth() is declared public (and importantly virtual) in Rectangle :), and since rect is reference to Square - call to rect.SetWidth() comes as a call to Square's private method because of C++'s virtual function mechanism!!

Don't forget C++ is tricky!

Note : the code I have discussed in this example is just for sake of example. Personally I would not have written such kind of code (at least) for any professional software.

Chaning const reference to pointer

Recently me and Chetan were puzzled, when we saw some code similar to -


=========**=========**=========Code=========**=========**=========



#include<iostream>

using namespace std;

class ABC {
public:
 ABC() {m_val = 0;}
 void change_state() {m_val ++;}
 ~ABC() {}
private:
 int m_val;
};


void function(const ABC *& p_abc) {
        // p_abc->change_state();     // Not Allowed
        p_abc = NULL;                 // Allowed
}

int main() {

 const ABC* p_abc = new ABC();  // p_abc is not const pointer!!

 // p_abc->change_state();      // Not Allowed
 function(p_abc);

 return 0;
}


=========**=========**=======Code End=======**=========**=========

We could not believe this (majic!!)
We thought this is wrong because p_abc is a const pointer!! - what do you say ;)
We even thought that there is some special compiler option!! which is allowing this to happen :)


The answer is, there is only one way to declare a const pointer is
Let's take example of constant pointer to integer -

int *const cnstPtr = new int();
The other two
const int * cnstObj1 = new int(); // and
int const * cnstObj2 = new int();
are declarations for pointer pointing to constant object! and the pointer itself is not constant!

Once again -
*cnstPtr = 5;       // OK - Object is not constant
cnstPtr = NULL;     // NOT OK - Pointer is constant

*cnstObj1 = 5;      // NOT OK - Object is constant
cnstObj1 = NULL;    // OK - Pointer is not constant
also
*cnstObj2 = 5;      // NOT OK - Object is constant
cnstObj2 = NULL;    // OK - Pointer is not constant

What if you want pointer and object both constant?
Use -

const int *const cnstPtrCnstObj1 = new int(); // or 
int const*const cnstPtrCnstObj2 = new int(); 

In this case -
*cnstPtrCnstObj1 = 5;     // NOT OK - Object is constant
cnstPtrCnstObj1 = NULL    // NOT OK - Pointer is constant

and
*cnstPtrCnstObj2 = 5;     // NOT OK - Object is constant
cnstPtrCnstObj2 = NULL    // NOT OK - Pointer is constant

Thanks to Chetan for showing the problem and then telling the cause :)

Saturday, April 24, 2010

Two wheeler (aka bike) : initial care

I bought Royal Enfield Thunderbird last Thursday. This bike is amazing!

I am doing some research on initial care of bike. You can use this information on your own risk, I do not have anything much to support my conclusions than commonsense and my BE (Mechanical) qualification.

Why do you need to take special care in initial months?
The same reason why baby needs special care in initial months :)
Engine which is heart of your bike is created using casting procedure and it is machined afterwards on CNC machines. It is highly possible that the surface finish of many parts inside the engine is not very smooth initially. When you start using engine, these parts get rubbed against each other. It is possible at this stage - if you have some small burs (small metal chips) remaining in the crankcase then these parts will get scratches. These initial scratches can result in big loss of efficiency and total engine life.

What are the general precautions one should take in initial months?
1. Give you bike some time to warm up!
Do not expect your bike ready for riding as soon as you start it. Think of it like someone has awakened you from sleep and now is forcing you for some heavy work.
When engine starts it takes some time for oil film layer to get developed between different friction-generating parts. If you give some time to your bike's engine to run on idling - this oil film will be developed before you actually go for ride.
2. Do not exceed speed (rpm) limits
Again as you know baby learns walking step by step and then after some time baby is able to run.
Similarly your vehicle first needs to be run on lower speeds, after each servicing max speed limit will be little higher. If you are lucky enough to have rpm meter then better keep eye on engine rpm than speed.
Reasons for initial speed limits are - same as the reasons explained in 'Why do you need to take special care in initial months?'
3. Try to ride on less crowded roads in initial days
Reason is simple - your engine will be running on almost constant rpm and also transmission system wont face much shocks.
4. Do not compromise on fuel and engine oil quality!
Using bad quality fuel/engine oil for bike is like eating bad quality food.
Remember - fuel is something which burns inside the engine cylinder, if it is of bad quality it is surely going to have bad effect on engine.
Engine oil does cleaning work inside engine and it is also responsible for maintaining temperature of engine unit. Engine oil is also responsible for reducing friction between the rubbing parts inside the engine.
5. If you get any vibration - noize or any other problem - get it repaired immediately.
Do not wait for servicing time to get these problems repaired. Ignoring these problem will result in making them bigger and making long life impact on your vehicle.
6. Avoid over-heating
Some people might think it is great to go for long rides in first few km. I think it is really good to go for long  rides in initial running, long runs do provide good conditions for engine and transmission system.
On highways engine rpm (speed) is almost constant and also gears are rarely shifted.
But do not forget that you should take enough breaks for engine to cool down. Over-heating might cause some problems (my gut feeling).

I will keep updating this post. If there are any mistakes in this post - please post comment. Your comments and suggestions are very much welcome.

Thanks to Harshad Sharma who helped me to think on these points.