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.

No comments:

Post a Comment