Search This Blog

Tuesday, June 9, 2009

Use polymorphism instead of type switching

//Reference: Item90 Avoid type switching: prefer polymorphism C++ Coding Standards
//THIS IS GOOD: use polymorphism

#include <iostream>
#include <string>
using namespace std;

class
language
{

public
:
virtual
void knock_knock() = 0; //pure virtual
virtual ~language() {}; //do not forget vdestructor!
};

class
cpp : public language
{

public
:
void
knock_knock(){
cout << "Knock Knock!" << endl;
cout << "Hi, I am C++!" << endl;
cout << "You are so fast!" << endl;
}
};


class
python : public language
{

public
:
void
knock_knock(){
cout << "Knock Knock!" << endl;
cout << "Hi, I am Python!" << endl;
cout << "You are batteries included!" << endl;
}
};


class
java : public language

{

public
:
void
knock_knock(){
cout << "Knock Knock!" << endl;

cout << "(10 seconds later...)" << endl;
cout << "Java: Who is this?" << endl;
}
};


void
better_knock_knock(language* lan)
{

//dynamic cast (served as downcasting) is not necessary here
if ( cpp *mycpp = dynamic_cast<cpp*>(lan)){

mycpp->knock_knock();
}

else

lan->knock_knock();
}


int
main()
{

//cpp *my_cpp = (cpp*)malloc(sizeof(cpp));
language *my_cpp = new cpp;
language *my_python = new python;
java *my_java = new java; //this works too

better_knock_knock(my_cpp);
better_knock_knock(my_python);
better_knock_knock(my_java);

free(my_cpp);
delete
my_python;
delete
my_java;
}

------------------------------------------------------------------------------------------------------------------
//The following is not good: type switching is hard to maintain
#include <iostream>
#include <string>
using namespace std;

//p.314 programming B.S.
enum language { CPP, PYTHON, JAVA };

struct
cpp
{

language type;
};


struct
python
{

language type;
};

struct
java
{

language type;
};


string knock_knock_cpp()
{

cout << "Knock Knock!" << endl;
cout << "Hi, I am C++!" << endl;
cout << "You are so fast!" << endl;
return
"";
}


void
knock_knock_python()
{

cout << "Knock Knock!" << endl;
cout << "Hi, I am Python!" << endl;
cout << "You are batteries included!" << endl;
}


void
knock_knock_java()
{

cout << "Knock Knock!" << endl;
cout << "(10 seconds later...)" << endl;
cout << "Java: Who is this?" << endl;
}


void
knock_language(language l_type)
{

switch
(l_type){
case
CPP: knock_knock_cpp(); break;

case
PYTHON: knock_knock_python(); break;
case
JAVA: knock_knock_java(); break;
}
}


int
main()
{

struct
cpp *my_cpp = (cpp*)malloc(sizeof(cpp));
my_cpp->type = CPP;
struct
python *my_python = new python;
my_python->type = PYTHON;
struct
java *my_java = new java;
my_java->type = JAVA;

knock_language(my_java->type);
knock_language(my_cpp->type);

free(my_cpp);
delete
my_python;
delete
my_java;
}

No comments: