Search This Blog

Tuesday, May 25, 2010

C++ is multi paradigm programming language

I might have read this sentence at least 10-15 times in different C++ books, but did not understand (and appreciate) at those times, what it means :(.

This link might help you - Programming paradigm

In my experience typical (big) software product written in C++ uses C++ in different way (techie word : uses different programming paradigms). The application side part is moreover in OOP and the core algorithm side part is moreover functional (both coded in C++ :)).

I wont write much on this subject (as I do not understand this subject well), but once you start looking at your C++ code taking into account programming paradigms used at different levels, you will feel more proud being a C++ developer :).

I got following comment from Yogeshwar Shukla on Buzz. Adding it to original post (with little modifications)  -
References to some books
i) Chapter 2. The C++ Programming Language. - Bjarne Stroustrup (very terse)
ii) Part I and II of Object Oriented Software Construction by Bertrand Meyer (very elaborate). This not really introduce you to the meaning of paradigm but explains OO paradigm.
iii) The best discussion is in -
Concepts, Models and Techniques in Programming. It has a formal specification of programming paradigm and the entire book is devoted to discussion of paradigms in computer science known as yet


I will try to add few more good links, in future.

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 :)