Tuesday, May 4, 2010

templates

Templates: This feature of C++ is comparable to generics of Java. Though both of them are implemented very differently internally serve similar purpose to an extent. Templates helps in writing code at one place for multiple data types. As word indicates we specify template for a class or function to work on multiple data types. Compiler generates version for the data type using which call is made.

Example:
// Template method example
template
T sum(T a, T b) {
return a + b;
}

...
int result = sum(10, 20);
float res = sum(10.2, 20.1);

// Error: templates follow strict type checking
// float result = sum(10, 20.2);

In above example compiler will generate int and float version of the method.

Similarly we write template for the class.
Example
// Template class example
template
class Sample {
private:
T data;
public:
T getData() {
return data;
}
void setData(T d);
};

// Notice how the method is defined outside class
template
void Sample::setData(T d) {
data = d;
}

main() {
Sample sample;
sample.getData();
}

Template argument can take default values. Default values become compile time constants.

template
class Sample {
private:
T container[MAX];
};


From C to C++ - misc...

Miscellaneous points:

Function declaration:
In C++ function must be declared before it is used. Function declaration/prototype should provide return type, number and type of arguments it take.

Example:
void display(char *);
void display(char *name); // better

Old C Structure: C++ has construct called structure which same as class except that in structure default access is public while in classes default access is private

Union and Enum: C++ has constructs called union and enum.
Example:


enum Gender { MALE, FEMALE };

union Data {
char name[20];
int age;
Gender sex;
};

Data d;
Gender sex;

Union is similar to structure except that it uses same memory location for all three items. i.e. size of the union is 20 (max of 3 items) while size of the same struct would be 28.

In C++ there is also a concept of anonymous union and enums

union {
char name[20];
int age;
};

enum { MALE, FEMALE };


name[0] = 'A';
age = 20;
int sex = MALE;

void *: We can assign any pointer to void* but cannot assign void* to another pointer, explicit conversion (type casting) is needed in 2nd operation.

Example:
void *vpointer;
chr *name;

name = (char *) vpointer; // conversion is needed
vpointer = name; // conversion not needed

bool: C++ has datatype similar to boolean in Java except that any integer can be converted to bool and vice-versa. integer != 0 is true while integer value 0 is interpreted as false

Example:
int num = 10;
bool isnum = true;

isnum = num;
cout <<>
num = isnum;
cout <<>

typedef: Typedef provides alias for an existing type. It doesn't create new type of its own.

typedef MYTYPE char*;
void display(char *);
void display(MYTYPE); // same as above hence throws an error

inline function: There are two kinds of inline functions.
  • Function explicitly declared as inline
Example:
inline void display() { // It's just a request to the compiler. Compiler can choose to ignore the request.
cout << "hello";
}

  • Function defined in the class body. Its more of C++ lingo than actual inline function as described above.

class sample {
public:
void display() {
cout << "hello"; // In lingo it is called defined inline.
}
};

Casting: Other than implicit data conversion C++ supports 4 different kind of type casting.
  • dynamic_cast: Checks at runtime if object is of given type. it returns address if object is of given type else returns 0
Sample *sample;
Base *base;
if (sample = dynamic_cast
(base)) {
...
}
  • static_cast: Used to convert between compatible types.
    • castless conversion i.e. int to long etc.
int rate = 10;
long base = static_cast(rate);
    • conversion from void*
Base* base = static_cast<>(vptr);

    • narrowing conversion i.e. from float/long to int
long rate = 10.6;
int base = static_cast(rate);

    • from derived to base and vice versa.
Base* base = static_cast (&derived);
  • const_cast: Used to convert const to non-const i.e.
const int a = 10;
int *p = const_cast(&a);

  • reinterpret_cast: Least safe of them all. Used to convert pointer to integers and vice versa.
int num = 65000;
int *address = reinterpret_cast(num);


RTTI (RunTime Type Identification): Other than dynamic_cast C++ provides another way to know the type of the object in runtime.
Example:
int num = 10;
typeid(num).name();

From C to C++

const: Const is C++ version of final in Java. Const can be used at many places.
  • const variable
    • any variable be it global, local, or in class if declared const becomes un-modifiable
  • const member function
    • Method in a class declared as const cannot modify variable inside
    • Declaration: void display() const; // remember const is after the brackets
    • Definition: void classname::display() const { ... }
  • const object
    • Can't modify any of the data member except ones declared as mutable
    • Can call only const methods as they are the only ones guaranteed not to modify object state

Use it often. Makes code more safer.

Example:

const char* name = "shreyas"; // string is constant pointer is not (read R to L)
name = "dhara";
*name = 'S' // Error

char const *location = "hyderabad"; // same as above

char * const weather = "hot"; // pointer is constant string is not
weather = "cool"; // Error
*weather = 'H';

const char * const weather = "hot"; // Both pointer and string it points to are constant
weather = "cool"; // Error
*weather = 'H'; // Error


Coonst and reference: If variable is declared const it's reference must also be declare const. Vice versa is not true
Example:
const int i = 10;
const int &ref = i;
int &err = i; // gives error

int j = 20;
const int &cref = j;

Note. if you return const string like "hello" your method declaration should be

const char* getname() {
return "hello";
}


mutable: Mutable let's you modify the member of const object. By definition const object is non-modifiable and you can only call const methods on them. By setting it mutable you can modify member variable of const object.
Example:
class Sample {
private:
mutable int num;

public:
// It is ironic that we have to declare method as const
// that actually modifies the variable
void setNum(int n) const {
num = n;
}
};

...
Sample s;
s.setNum(20);

namespace: It is similar to java's package.
Example:
namespace sample {

// Nested namespace is allowed
namespace nested {

}

class Base {
};

void display();
} // namespace sample

// Definition outside namespace
void sample::display() {
cout << "outside namespace";
}

// We can give alternate name to a namespace
namespace very_very_long_namespace {

class Trial {
};

}

namespace vvln = very_very_long_namespace;

int main() {
sample::Base base;

// Alternate way
using namespace sample;
Base base;

// Error cannot have namespace at global level
// namespce local {
// }
}