Saturday, June 16, 2012

Const and Reference

Const, Pointer and Reference in C/C++ Passing by reference or pointer in doubleit resulting the values in main will be altered
//in C no reference using pointers changes the value of memory location resulting altering the values in main
#include <stdio.h>
 
void doubleit( int *x, int *y){
   *x *= 2;
   *y *= 2;
}
 
int main(void){
   int x = 10;
   int y = 5;
   doubleit( &x, &y);
   printf("%i %i",x,y);
   return 0;
}
//C++ using references change the value of memory location resulting altering the values in main
#include <stdio.h>
 
void doubleit( int &x, int &y){
   x *= 2;
   y *= 2;
}
 
int main(void){
   int x = 10;
   int y = 5;
   doubleit( x, y);
   printf("%i %i",x,y);
   return 0;
}
//C/C++ passing by values the values in main will not change, it makes a copy x, y for doubleit and it will be destroyed when function is returned
#include <stdio.h>
 
void doubleit( int x, int y){
   x *= 2;
   y *= 2;
}
 
int main(void){
   int x = 10;
   int y = 5;
   doubleit( x, y);
   printf("%i %i",x,y);
   return 0;
}
//Const, Reference and values
#include <stdio.h>
 
 
//void doubleit(int x, int y){  //unchange the values x, y in main copy varibles and keep the original in main
//void doubleit(int &x, int &y){  //change values x, y in main by reference 
void doubleit(const int &x, const int &y){ // unchange the values x, y in main by const compile will check if it is altered can read only
// which will cause variable to be passed by reference without copying but stop it from being altered.
//x *= 2;
//y *= 2;
 int i = x*2;
 int j = y*2;
 printf("%i %i\n",x,y);
}
 
int main(void){
 int x = 10;
 int y = 5;
  
 doubleit(x,y);
  
 printf("%i %i",x,y);

  
 return 0;
}
Even more useful is a pointer (constant or otherwise) to a ‘const’ value. This is useful for returning constant strings and arrays from functions which, because they are implemented as pointers, the program could otherwise try to alter and crash. Instead of a difficult to track down crash, the attempt to alter unalterable values will be detected during compilation. For example, if a function which returns a fixed ‘Some text’ string is written like char *Function1() { return “Some text”;} then the program could crash if it accidentally tried to alter the value doing Function1()[1]=’a’; whereas the compiler would have spotted the error if the original function had been written const char *Function1() { return "Some text";} because the compiler would then know that the value was unalterable. (Of course, the compiler could theoretically have worked that out anyway but C is not that clever. Passing an object by reference.
// C++
class Type; // defined somewhere before, with the appropriate operations
void swap( Type & a, Type & b ) {  //like variables need & for function
   Type tmp = a;
   a = b;
   b = tmp;
}
int main() {
   Type a, b;
   Type old_a = a, old_b = b;
   swap( a, b );    //like in the previous example for variables just the name
   assert( a == old_b );
   assert( b == old_a ); 
}
The swap function above changes both its arguments through the use of references. The closest code in Java:
//Java
public class C {
   // ...
   public static void swap( C a, C b ) {
      C tmp = a;
      a = b;
      b = tmp;
   }
   public static void main( String args[] ) {
      C a = new C();
      C b = new C();
      C old_a = a;
      C old_b = b;
      swap( a, b ); 
      // a and b remain unchanged a==old_a, and b==old_b
   }
}
The Java version of the code will modify the copies of the references internally, but will not modify the actual objects externally. Java references are C pointers without pointer arithmetic that get passed by value into functions. Can I access private members from outside the class without using friends in C++? Yes, you can Conceptually in C/C++
#include <iostream>
#include <string>
using namespace std;
int main(){
 int i = 2;
 int *j = &i; //j and i are the same in memory location
 *j = 4;  // change value of i because the same memory location for i and j
 cout << i << endl;
return 0;

AccessMemoryOfPrivateUseFriend.cpp: In function ‘Student Show(std::string, int)’:
AccessMemoryOfPrivateUseFriend.cpp:7: error: ‘std::string Student::name’ is private
Therefore we need a friend keyword function like this.
#include <iostream>
#include <string>
using namespace std;

class Student {
     private:
       string name;
       int grade;
     public:
       void ShowStudent() { cout << name << " " << grade << endl;}
       friend Student Show(string, int); //friend function to access class private
 };
Student Show(string s, int y)
{
   Student T;
   T.name = s;
   T.grade = y;
   return T;
}

int main(){
  Student S;
  S = Show("Tom", 10);
  S.ShowStudent();
  return 0;
 }
Output: Tom 10
Without Friend we can do as with the above for integer. 
Create another class with the same layout as the object with private members but with private changed to public. Create a variable of pointer to this class. Use a simple cast to point this to your object with private members and try calling a private function.
#include <iostream>
#include <string>
using namespace std;

class Student {
     private:
     string name;
     int grade;
  public:
     void ShowStudent() { cout << name << " " << grade << endl;}
 };
class Me {
 public: 
  string myname;
  int mygrade;
}; 
int main(){
  Student T;
  Me *p;
  p = (Me*)&T;
  p->myname = "Tom";
  p->mygrade = 10;
  T.ShowStudent();
  return 0;
 }
Output: Tom 10 (we get the same output as friend function before without using friend)
Using template to access private members of the class.
#include <iostream>
using namespace std;
class safe
{
    int money;

public:
    safe() : money(1000000){ cout << "Constructor is called initializes 1000000" << endl;}

    template <typename T> //template
    void backdoor()
    {
     money -= 50000;
     cout << "Template "<< money << endl;
    }
    //void take(){ safe T; T.money -= 1; cout << T.money << endl;}
    friend void take(safe);
};
void take(safe T) { T.money -= 1; cout << "Friend " << T.money << endl;}

//class me;
//class key;

template <> //template specialization
void safe::backdoor<class key>()  //void safe::backdoor<class key>()
{
    // My specialization.
    money -= 100000;
    cout << "Template specialization " << money << "\n";
}

int main()
{
    safe s;
    s.backdoor<class key>();
    s.backdoor<key>();
    s.backdoor<int>();
    take(s); //error: ‘class safe’ has no member named ‘take’ just a friend not a member
}

Output: Constructor is called initializes 1000000 Template specialization 900000 Template specialization 800000 Template 750000 Friend 749999 In case of class Student before, using template specialization(empty template <>) can modify the private data members using template function is not compiled until an instantiation with specific template arguments is required.
#include <iostream>
#include <string>
using namespace std;

class Student {
     private:
     string name;
     int grade;
  public:
     void ShowStudent() { cout << name << " " << grade << endl;}
  template <typename T> //template
     void change(){ name = "Thomas"; grade = 9;}
 };
template <>  //template specialization
void Student::change<class modify>()  //void safe::backdoor<class key>()
{
    // My specialization.
    name = "Hacker";
    grade = 10;
    cout << "Template specialization " << "\n";
}

int main(){
  Student T;
  T.change<modify>();
  T.ShowStudent();
  T.change<int>();
  T.ShowStudent();
  return 0;
 }
Output: Hacker 10 Thomas 9

No comments: