FRIEND CLASSES

Some classes are friend to other classes, it means they can access even private data member of other class. Let’s exam the following script to figure out the concept.

// Example program
#include 
#include 
using namespace std;
class Coord;
class Display{
 public:
    Display(){}
    void show(const Coord& t);
};
class Display2;
class Coord{
 private:
    double m_dx, m_dy;
 public:
    Coord(double dx = .0, double dy = .0){
        m_dx = dx;
        m_dy = dy;
    }
    friend double getDistance(const Coord& t);
    friend Coord addPoint(const Coord& t1, const Coord& t2);
    friend Display2;
    friend void Display::show(const Coord& t);
};
class Display2{
 public:
    Display2(){}
    void show(const Coord& t){
        printf("[ %3.1f , %3.1f ] \n",t.m_dx,t.m_dy);
    }
};
double getDistance(const Coord& t){
    return pow(t.m_dx*t.m_dx + t.m_dy*t.m_dy,.5);
}
Coord addPoint(const Coord& t1, const Coord& t2){
    return Coord(t1.m_dx + t2.m_dx, t1.m_dy + t2.m_dy);
}
void Display::show(const Coord& t){
    printf("{ %3.1f , %3.1f } \n",t.m_dx,t.m_dy);
}
int main()
{
    Coord t1(3,4), t2(6,8);
    printf("%3.1f\n", getDistance(t1));
    printf("%3.1f\n", getDistance(addPoint(t1,t2)));
    Display2 d1;
    Display d;
    d1.show(t1);
    d.show(t1);
}<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>

This example tells  a quite completed story about friend classes.

Class Display2 is a friend class of Coord while member function Display::show() is a friend function of Coord.

Note: class Display declares  a function that has an argument of class Coord, therefore before its definition we need to declare Coord. However the function show that access data members of Coord is only defined after Coord definition.

https://newton.newtonsoftware.com/career/CareerHomeSearch.action?clientId=8a7883c6603459fe016047c420730543

Advertisements

FRIEND FUNCTIONS

This a function that is NOT a function member of a CLASS but has a right to access all data member of it. For example, the following friend functions: one just prints data member and another add two objects of a class.

// Example program
#include <iostream>
using namespace std;
class Trial{
 private:
    int m_a;
 public:
    Trial(int a=0){
        m_a = a;
    }
    void setValue(int a){
        m_a = a;
    }
    friend int getValue(const Trial& t){
        return t.m_a;
    }
    friend Trial addT(const Trial& t1, const Trial& t2){
        return Trial(t1.m_a + t2.m_a);
    }
};

int main()
{
    Trial t1(4), t2(5);
    printf("%d\n", getValue(t1));
    printf("%d\n", getValue(addT(t1,t2)));
}

As we can see , friend function can getValue can access private member data of class Trial.

CONSTRUCTOR – ERROR-PRONE

Constructor is neccessary element of any classes. It’s basic stuff. However, there is a case when errors encountered and we find it difficult to debug. Here is one of them.

// Example program
#include
using namespace std;
class Trial{
private:
int m_a;
public:
Trial(int a){
m_a = a;
}
int getValue() const {
return m_a;
}
void setValue(int a){
m_a = a;
}
};

int main()
{
Trial t;
t.setValue(3);
printf("%d",t.getValue());
}

It will cause an error because when we create an object of class Trial without initialization list, it need a DEFAULT CONSTRUCTOR, but we forgot to define it. To solve this problem, there is very simple way. Here you are:


// Example program
#include <iostream>
using namespace std;
class Trial{
private:
int m_a;
public:
Trial(int a=0){
m_a = a;
}
int getValue() const {
return m_a;
}
void setValue(int a){
m_a = a;
}
};

int main()
{
Trial t;
t.setValue(3);
printf("%d",t.getValue());
}

Sorting algorithms

#include <iostream>
using namespace std;
// ascending order
template<class T>
bool ascending(T first, T second){
	return first<=second;
}
// descending order
template<class T>
bool descending(T first, T second){
	return first>=second;
}
// swap two elements of a given array
template<class T>
void swap(T arr[],unsigned ii,unsigned jj){
	T temp;
	temp=arr[ii];
	arr[ii]=arr[jj];
	arr[jj]=temp;
}
// bubble sort
/*
The idea is: For a particular ii, compare it with all the next element, if there is any element that breaks out the expected order than swap positions
*/
template<class T>
void bubbleSort(T arr[],unsigned size,bool(*comparison)(T,T)){
	for (unsigned ii=0;ii<size-1;++ii){
		for (unsigned jj=ii+1;jj<size;++jj){
			if (!comparison(arr[ii],arr[jj])) swap(arr,ii,jj);
		}
	}
}
// insertion sort
/*
The idea is: For a particular ii, compare it with the previous subarray
*/
template<class T>
void insertionSort(T arr[],unsigned size,bool(*comparison)(T,T)){
	for(unsigned ii=0;ii<size;++ii){ 		unsigned jj=ii; 		while (jj>0){
			if (!comparison(arr[jj-1],arr[jj])) swap(arr,jj-1,jj);
			jj--;
		}
	}
}
// selection sort
/*
The idea is: For a particular ii, seek for the min(max) of the subarray after it, if the found element is different from ii, then swap
*/
template<class T>
void selectionSort(T arr[],unsigned size,bool(*comparison)(T,T)){
	for(unsigned ii=0;ii<size-1;++ii){
		unsigned iMin=ii;
		for (unsigned jj=ii+1;jj<size;++jj){
			if (!comparison(arr[iMin],arr[jj])) iMin=jj;
		}
		if (iMin!=ii) swap(arr,iMin,ii);
	}
}
//merge sort
/*
The idea is: divide and conquer.
*/
// merge function
template<class T>
void merge(T arr[],unsigned start,unsigned mid,unsigned end){
	unsigned ii(start),jj(mid+1),kk(0);
	T temp[end-start+1];
	while (ii<=mid && jj<=end){
		if (arr[ii]<arr[jj]){
			temp[kk]=arr[ii];
			ii++;
		}else{
			temp[kk]=arr[jj];
			jj++;
		}
		kk++;
	}
	if (ii<=mid){
		for (unsigned tt=ii;tt<=mid;++tt,++kk){
			temp[kk]=arr[tt];
		}
	}
	if (jj<=end){
		for(unsigned tt=jj;tt<=end;++tt,++kk){
			temp[kk]=arr[tt];
		}
	}
	for (unsigned tt=0;tt<kk;++tt){
		arr[start+tt]=temp[tt];
	}
}
// recursion function
template<class T>
void mergeSort(T arr[],unsigned start,unsigned end){
	if (start<end){
		unsigned mid=(start+end)/2;
		mergeSort(arr,start,mid);
		mergeSort(arr,mid+1,end);
		merge(arr,start,mid,end);
	}
}
// Shell sort
/*
The idea is: Develop from insertion sort and use gap to avoid moving too far
*/
template<class T>
void shellSort(T arr[],unsigned size){
	for (unsigned gap=size/2;gap>0;gap/=2){
		cout<<"ga="<<gap<<endl;
		for (unsigned ii=gap;ii<size;++ii){
			cout<<"ii="<<ii<<endl; 			T temp=arr[ii]; 			unsigned jj; 			for(jj=ii;jj>=gap && arr[jj-gap]>temp;jj-=gap){
				cout<<"jj="<<jj<<endl;
				arr[jj]=arr[jj-gap];
			}
			arr[jj]=temp;
		}
	}
}

Linked List

LinkedList.h

#ifndef LINKEDLIST_H
#define LINKEDLIST_H
struct Link {
	int num;
	Link* next;
};
class LinkedList{
private:
	Link *first,*last;
public:
	LinkedList();	// default constructor
	LinkedList(unsigned size,int uniformValue); // initialize a list with size element of uniformValue
	LinkedList(int *start, int *end); // initialize a list from start to end (not included end)
	void push_front(int value);	// add new item to the front of the list
	void push_back(int value);	// add new item to the end of the list
	int size();					// return the size of the list
	void display();				// display content of the list
	int operator [](unsigned index);	// overloading operator []
	int front();		// return the first element of the list
	int back(); 		// return the last element of the list
};
#endif

LinkedList.cc

#include <iostream>
#include <climits>
#include "LinkedList.h"
using namespace std;
//default constructor
LinkedList::LinkedList():first(NULL),last(NULL){}
// initialize a list with size element of uniformValue
LinkedList::LinkedList(unsigned size,int uniformValue){
	Link* arr=new Link[size];
	for (unsigned ii=0;ii<size;++ii){
		arr[ii].num=uniformValue;
		if (ii<size-1) arr[ii].next=arr+ii+1;
		else arr[ii].next=NULL;
	}
	first=arr;
	last=arr+size-1;
}
// initialize a list from start to end (not included end)
LinkedList::LinkedList(int *start, int *end){
	int size=end-start;
	Link* arr=new Link[size];
	for (unsigned ii=0;ii<size;++ii){
		arr[ii].num=*(start+ii);
		if (ii<size-1) arr[ii].next=arr+ii+1; 		else arr[ii].next=NULL; 	} 	first=arr; 	last=arr+size-1; } // add a new item to the front of the list void LinkedList::push_front(int value){ 	Link* pt=new Link;	//create a new atom  	pt->num=value;
	pt->next=first;
	first=pt;
	if (last==NULL) last=first; // if there is only one entity in the list so first=last
}
// add a new item to the back for the list
void LinkedList::push_back(int value){
	Link* pt =new Link;
	pt->num=value;
	pt->next=NULL;
	if (last==NULL) {
		last=pt;
		first=last;
	}else{
		last->next=pt;
		last=pt;
	}
}
// return the size of the list
int LinkedList::size(){
	Link* pt(first);
	int count(0);
	while(pt!=NULL){
		count++;
		pt=pt->next;
	}
	return count;
}
// display the content of the list
void LinkedList::display(){
	Link* pt(first);
	while(pt!=NULL){
		cout<<"["<<pt->num<<"]"; 		pt=pt->next;
	}
	cout<<endl; } // overloading operator [] int LinkedList::operator [] (unsigned index){ 	Link* pt(first); 	int count(0); 	while(pt!=NULL){ 		if (count==index) { 			return pt->num;
			break;
		}
		count++;
		pt=pt->next;
	}
	if (pt==NULL) return INT_MAX;
}
// return the first element of the list
int LinkedList::front(){
	if (first==NULL) return INT_MAX;
	return first->num;
}
// return the last element of the list
int LinkedList::back(){
	if (last==NULL) return INT_MAX;
	return last->num;
}

Integer in binary representation

#include <iostream>
#include <list>
using namespace std;
void print(const list<int>& li){
	list<int>::const_iterator it;
	short countT(0);
	for(it=li.begin();it!=li.end();++it){
		cout<<*it;
		countT++;
		if (!(countT%4)) cout<<" ";
	}
	cout<<endl;
}
list<int> PoDeToBi(int num){
	list<int> result(16,0);
	list<int>::reverse_iterator rit(result.rbegin());
	while (num!=0 && rit!=result.rend()){
		*rit=num%2;
		num/=2;
		++rit;
	}
	return result;
}
list<int> SumOfBi(const list<int> B1,const list<int> B2){
	list<int> result(16,0);
	list<int>::const_reverse_iterator crit1(B1.rbegin());
	list<int>::const_reverse_iterator crit2(B2.rbegin());
	list<int>::reverse_iterator ritR(result.rbegin());
	int remT(0);
	while (crit1!=B1.rend() && crit2!=B2.rend() && ritR!=result.rend()){
		if (remT+*crit1+*crit2<=1){
			*ritR=*crit1+*crit2+remT;
			remT=0;
		}
		else {
			*ritR=remT+*crit1+*crit2-2;
			remT=1;
		}
		crit1++;
		crit2++;
		ritR++;
	}
	return result;
}
list<int> NeDeToBi(int num){
	list<int> result(16,0);
	result=PoDeToBi(-num);
	list<int>::iterator it;
	for(it=result.begin();it!=result.end();++it){
		if (*it==0) *it=1;
		else *it=0;
	}
	result=SumOfBi(result,PoDeToBi(1));
	return result;
}
int BiToDe(const list<int>& Bi){
	int sum=0;
	list<int>::const_iterator it(Bi.begin());
	if (*it==0){
		it++;
		while(it!=Bi.end()){
			sum=sum*2+*it;
			++it;
		}
		return sum;
	}else{
		list<int> BiT(Bi);
		list<int>::iterator itT;
		for(itT=BiT.begin();itT!=BiT.end();++itT){
			if (*itT==0) *itT=1;
			else *itT=0;
		}
		itT=BiT.begin(); itT++;
		while(itT!=BiT.end()){
			sum=sum*2+*itT;
			++itT;
		}
		return -(sum+1);
	}
}
int main(){
	int a(23),b(15),c(-100);;
	list<int> la,lb,lc;
	la=PoDeToBi(a);
	lb=PoDeToBi(b);
	lc=NeDeToBi(c);
	print(la);print(lb);print(lc);
	cout<<BiToDe(la)<<endl;
	cout<<BiToDe(lb)<<endl;
	cout<<BiToDe(lc)<<endl;
}

Algorithm: Mutating Sequence Operations

#include <iostream>
#include <iomanip>
#include <algorithm> //copy, copy_backward, swap, iter_swap, swap_ranges, transform, replace, replace_if, replace_copy, replace_copy_if, fill, fill_n, generate, generate_n, remove, remove_if, remove_copy, remove_copy_if, unique, unique_copy, reverse, reverse_copy, rotate, rotate_copy, random_shuffle, partition, stable_partition
#include <utility>
#define LIMIT 6
#define LIMIT2 8
#define FIND_ELEMENT 11
using namespace std;
/*
Function declaration
*/
void add(int&); //add value to each array element
void print(const int[], const int&); // print arrays
bool isOdd(const int&); // check if element is odd
bool isConsecutive(const int&, const int&); // check if two numbers are consecutive
bool isMoreThan3(const int&,const int&); // check if twi numbers are more or less than 3
int add1(const int&); // add value to each array element but return a value
int mul1(const int&, const int&); // multiply two integers
bool isNeg(const int&); // check if the argument is negative
int gogo();
/*
Main function
*/
int main() {
    int* pt;
    int arr[]={2,3,5,6,7,8};
    int arr2[]={1,2,3,4,5,6,7,8};
    int arr3[]={-6,-5,-4,-3,-2,-1};
    int arr4[]={1,2,3,4,5,6};
    cout<<"Two original arrays:"<<endl;
    print(arr,LIMIT);
    print(arr2,LIMIT2);
    //copy
    cout<<"COPY OPERATION"<<endl;
    copy(arr,arr+LIMIT,arr2);
    cout<<"Two modified arrays:"<<endl;
    print(arr,LIMIT);
    print(arr2,LIMIT2);
    //copy_backward
    cout<<"COPY_BACKWARD OPERATION"<<endl;
    cout<<"Two original arrays:"<<endl;
    print(arr,LIMIT);
    print(arr2,LIMIT2);
    copy_backward(arr,arr+LIMIT,arr2+LIMIT2);
    cout<<"Two modified arrays:"<<endl;
    print(arr,LIMIT);
    print(arr2,LIMIT2);
    //swap
    cout<<"SWAP OPERATION"<<endl;
    cout<<"Two original arrays:"<<endl;
    print(arr3,LIMIT);
    print(arr4,LIMIT);
    swap(arr3,arr4);
    cout<<"Two modified arrays:"<<endl;
    print(arr3,LIMIT);
    print(arr4,LIMIT);
    //iter_swap
    cout<<"ITER_SWAP OPERATION"<<endl;
    cout<<"Two original arrays:"<<endl;
    print(arr3,LIMIT);
    print(arr4,LIMIT);
    iter_swap(arr3+2,arr4+2);
    cout<<"Two modified arrays:"<<endl;
    print(arr3,LIMIT);
    print(arr4,LIMIT);
    //swap_ranges
    cout<<"SWAP_RANGES OPERATION"<<endl;
    cout<<"Two original arrays:"<<endl;
    print(arr3,LIMIT);
    print(arr4,LIMIT);
    swap_ranges(arr3,arr3+2,arr4+3);
    cout<<"Two modified arrays:"<<endl;
    print(arr3,LIMIT);
    print(arr4,LIMIT);
    //transform
    cout<<"TRANSFORM OPERATION"<<endl;
    cout<<"The original array:"<<endl;
    print(arr3,LIMIT);
    print(arr4,LIMIT);
    cout<<"The first implementation of transform operation"<<endl;
    transform(arr3,arr3+LIMIT,arr3,add1);
    cout<<"The modified array:"<<endl;
    print(arr3,LIMIT);
    cout<<"The second implementation of transform operation"<<endl;
    transform(arr3,arr3+LIMIT,arr4,arr3,mul1);
    cout<<"The modified array:"<<endl;
    print(arr3,LIMIT);
    //replace
    cout<<"REPLACE OPERATION"<<endl;
    cout<<"The original array:"<<endl;
    print(arr3,LIMIT);
    replace(arr3,arr3+LIMIT,-3,4);
    cout<<"The modified array:"<<endl;
    print(arr3,LIMIT);
    //replace_if
    cout<<"REPLACE_IF OPERATION"<<endl;
    cout<<"The original array:"<<endl;
    print(arr3,LIMIT);
    replace_if(arr3,arr3+LIMIT,isNeg,300);
    cout<<"The modified array:"<<endl;
    print(arr3,LIMIT);
    //replace_copy
    cout<<"REPLACE_COPY OPERATION"<<endl;
    cout<<"The original array:"<<endl;
    print(arr3,LIMIT);
    print(arr4,LIMIT);
    replace_copy(arr3,arr3+LIMIT,arr4,4,1000);
    cout<<"The modified array:"<<endl;
    print(arr3,LIMIT);
    print(arr4,LIMIT);
    // fill
    cout<<"FILL OPERATIOM"<<endl;
    cout<<"The original array:"<<endl;
    print(arr3,LIMIT);
    fill(arr3,arr3+3,1986);
    cout<<"The modified array:"<<endl;
    print(arr3,LIMIT);
    // fill_n
    cout<<"FILL_N OPERATIOM"<<endl;
    cout<<"The original array:"<<endl;
    print(arr3,LIMIT);
    fill_n(arr3+3,3,1991);
    cout<<"The modified array:"<<endl;
    print(arr3,LIMIT);
    // generate
    cout<<"GENERATE OPERATION"<<endl;
    cout<<"The original array:"<<endl;
    print(arr3,LIMIT);
    generate(arr3,arr3+LIMIT,gogo);
    cout<<"The modified array:"<<endl;
    print(arr3,LIMIT);
    // unique
    int arr5[]={1,1,3,4,4,5};
    cout<<"UNIQUE OPERATION"<<endl;
    cout<<"The original array:"<<endl;
    print(arr5,LIMIT);
    pt=unique(arr5,arr5+LIMIT);
    cout<<"The modified array:"<<endl;
    print(arr5,LIMIT);
    cout<<pt-arr5+1<<"position has been checked for their duplication"<<endl;
}
/*
Function definition1
*/
void add(int& i) {
	i += 3;
}
void print(const int arr[], const int& SIZE) {
	cout << "[";
	for (unsigned i = 0; i<SIZE; ++i) {
		cout << setw(2) << arr[i];
		if (i != SIZE - 1) cout << ",";
	}
	cout << "]" << endl;
}
bool isOdd(const int& i) {
	return i % 2;
}
bool isConsecutive(const int& i, const int& j) {
	return abs(i - j) == 1 ? true : false;
}
bool isMoreThan3(const int& i, const int& j){
    return abs(i-j)<3?true:false;
}
int add1(const int& i){
    return i+3;
}
int mul1(const int& i, const int& j){
    return i*j;
}
bool isNeg(const int& i){
    return i<0;
}
int gogo(){
    return 1212;
}