const_cast – cpp

Constant casting (const_cast) is when you have a variable that is declared constant but you want to remove that constant restriction from that variable. In normal C language the (int) casting would suffice, but it may throw up some errors that you really did not want!!.. so using const_cast you can remove the constant restriction with abit more safer feeling as such, and also the const_cast would be upgrade/updated on different versions/compilers etc.

To remove the constant casting the syntax for const_cast is

returnvalue = const_cast<return type>(casting value)

where the returnvalue is the value to be returned from the casting, the return type is what you want the returning value type to be and then the value (casting value) is the actual value (constant value) to be cast.

Here is a another example with abit more code

#include <iostream>
 
using namespace std;
 
int main()
{
  const int pies = 3;
  int &newPies = const_cast<int&>(pies);
  cout << "pies = " << pies << endl;
  newPies += 2;
  cout << "new pies = " << newPies << endl;
 
 // where as you cannot alter the old pies value .. 
 // pies+=2;///error !!
  return 0;
}

and the output would be

pies = 3
new pies = 5

Keeping values a constant is a good thing, but sometimes you want to alter the constant value !!.

As someone said on my similar post on code call

Here is some code to demonstrate how to do something similar to the strstr function, from what “dcs” member said “An example that comes to mind would be writing a function similar to C’s strstr function: the strings passed should not be modified by the function and should therefore be const-qualified. But the returned pointer need not be const, even though it may point to a position in the string which was passed as const-qualified.”

#include <iostream>
#include <string.h>
 
using namespace std;
 
char* codecallStrStr(const char* p1, const char* p2)
{
      bool found;
     // loop through the first string
      while (*p1)
      {
	  // if there is a match between the frist string character and the second string character
	  if (*p2 == *p1)
	  {
	    if (strlen(p2) <= strlen(p1))
	    {
	      found = true;
	      for (int i =0; i < strlen(p2); i++)
	      {
		if (p2[i] != p1[i]) {
		  found = false;
		  break;
		}
	      }
	      if (found) 
	      {
		return const_cast<char*>(p1);
	      }
	    }
	  }
	  p1++;
      }
      return 0;
}
 
int main()
{
    char *searchStr = "hi thre there k ";
    char *pr = codecallStrStr(searchStr, "there");
 
    // check to make sure it was found.
    if (pr)
    {
      cout << pr << endl;
    }
    else
      cout << "no found" << endl;
}

output would be

there k

Reinterpret_cast – cpp

The casting of variables is one way to convert one type of variable to another, for example if you wanted to have Pi being a double number e.g. 3.14 and then wanted to have the integer value instead (just the whole number) then that is a cast of the variable.

The classic was of casting in C language is like

double pi = 3.14;
int piInt = (int)pi;

and the (int) is the casting of one type to another.

But it is better to use the c++ casting techniques, static_cast, const_cast, dynamic_cast and reinterpret_cast. I am going to do a reinterpret_cast, and this is a way of converting a pointer to a variable from one type to another that is not of a similar type and it will try and fit the cast into the return type.

The syntax for reinterpret_cast is

returnvalue = reinterpret_cast<return type*>(casting value);

where the return value is what is casted and the return type is what you want to be casted to, and the casting value is what you want to be casting from.

One good example is how to use the reinterpret_cast is to convert one type into a void pointer (void *) and then back again, it is not really much use in this case and also reinterpret_cast does not do any type checking etc, it will just try and fit the casting value into the return type and if it fits, great, if it does not, great, it really does not care, so that is why it is better to use the static_cast (shall do a tutorial on that next).

#include <iostream>
 
int main()
{
  int *aInt = new int(10);
  cout << "A value = " << *aInt << endl;
 
  void *bVoid = reinterpret_cast<void*>(aInt);
  int *aBack = reinterpret_cast<int*>(bVoid);
 
  cout << "COME BACK TO ME !! A value again = " << *aBack << endl;
}

and the output would be

A value = 10
COME BACK TO ME !! A value again = 10

Since you are playing with pointers to memory locations then if you alter the value of A in that example the returning back cast would also reflect the new value as well.

Here is a example of just that, altering the value within the casted variable and also reinterpret_cast does not matter if you are using standard variable types like int,float etc.. it can also work on classes as well.

#include <iostream>
 
using namespace std;
 
class classA
{
  public:
    int valueX;
    int valueY;
 
    classA() { valueX = 0; valueY = 0;}
 
};
 
int main()
{
  classA *a = new classA();
  a->valueX = 10;
  a->valueY = 30;
  cout << "Value of X = " << a->valueX << " Value of Y = "  << a->valueY << endl;
 
  void *aClassVoid = reinterpret_cast<void*>(a);
 
  a = reinterpret_cast<classA*>(aClassVoid);
 
  cout << "COME BACK To me !! Value of X = " << a->valueX << " Value of Y = "  << a->valueY << endl;
 
  cout << "Value of X = " << a->valueX << " Value of Y = "  << a->valueY << endl;
  aClassVoid = reinterpret_cast<void*>(a);
  // but if you alter the values within a variable once you have done the first cast.
  cout << "After the first cast .. Value of X = " << a->valueX << " Value of Y = "  << a->valueY << endl;
  a->valueX = 0;
  cout << "After settings the value to 0 .. Value of X = " << a->valueX << " Value of Y = "  << a->valueY << endl;
  //and try again with the casting with the aClassVoid
  classA *AP = reinterpret_cast<classA*>(aClassVoid);
 
  cout << "COME BACK To me !! Value of X = " << AP->valueX << " Value of Y = "  << AP->valueY << endl;
 
  cout << "The last reinterpret_cast leaves the value as 0 for valueX because it is still only pointing to the same place as 'a'" << endl;
 
   return 0;
}

and the output is

Value of X = 10 Value of Y = 30
COME BACK To me !! Value of X = 10 Value of Y = 30
Value of X = 10 Value of Y = 30
After the first cast .. Value of X = 10 Value of Y = 30
After settings the value to 0 .. Value of X = 0 Value of Y = 30
COME BACK To me !! Value of X = 0 Value of Y = 30
The last reinterpret_cast leaves the value as 0 for valueX because it is still only pointing to the same place as 'a'

Hope that helps in how to use reinterpret_cast, but as stated before, best to use static_cast because that would give some information if the casting was successful. Also reinterpret_cast can also be used on function pointers to, which is kinder cool. The main reason for reinterpret_cast is that it uses minimal type checking, and if the target as similar bit patterns to the original then we are good to go as such in the reinterpret_cast way of things.

Polymorphism

Polymorphism means that you are deriving from a base class to create a new class, and the polymorphism is when you derive from the base class and implement a interface (virtual function in c++ speak as such) functions.

In C++ a virtual function would be

virtual void printName() = 0;

the = 0 means to set the virtual function to point to nothing (pure virtual function).

You could put some code within {} and still call it a virtual function, but that is taking away from the interface idea. (Java,C# and PHP use the interface structures)

In the code below, I have a const string (constant string) and as we know a constant string cannot be altered so to define this string when the constructor is called you place the variable name after the constructor and set it up to the constant value, e.g..

class Shape
{
     const string name;
      // constructor
     Shape(const string& constructorName) : name(constructorName) {};
}

This will setup the constant string when the Shape class has been created on the heap (memory allocation).

To call a parent class, Shape in this instance, constructor you just do something very similar to the setting of the constant string, you place it after the constructor in the subclass and put the parent class that you want to call its constructor after the “:” as

class Rectangle 
{
      Rectangle(const string& constructorName) : Shape(constructorName) {}
}

you can place more code into the {} for the Rectangle constructor still, but the “Shape(constructorName) is calling the parent class “Shape” constructor.

If you do not define the virtual pure function within the derived class, when you try to compile the error would be something similar to

poly.cpp:46: error: cannot allocate an object of abstract type 

const – constants in functions

Const is a constant type, it makes what is talking to a constant value. The value cannot be altered in anyway, a good reason for this could be for a constant string for error codes or if the value of a variable needs to be checked but not altered in anyway.

Pointers can be constants too and also there are many places that you can put the const type. Here are some examples

// constant integer value
const int constValue = 3;
// normal value.
int Value = 10;
 
//pointers can be constants too
const int * pConst = &constValue;
//the pConst is a pointer to a const int value, the value pointed to cannot be altered, but the pConst memory location can to where it is pointing to.
int * const pConst = &Value;
// here the pConst value pointed to can be altered, but the memory location for the pConst for where it is pointing to cannot be altered (always pointing to the same place).
// of course you can have both.
const int * const pConstConst = &constValue;
// here it is a const int value that has a const pointer that is not allow to change.

You can also place const around the function definition as well, there are three places where you can place the const type.

const int returnValue(const int value1) const;

In the order of the const on the function definition list

  1. constant return type, cannot alter the returned value (unless you place it in a another variable)
  2. constant parameter passed, you cannot alter the value1 in this case
  3. constant “this”, this is the class that it is placed in and you cannot alter any values within that class

I have placed below some code that will hopefully explain more for the different types and also the error codes that come if you try and compile up if you are not obeying const rules and I placed the code below for what caused the error.

#include 

using namespace std;

// there are 3 different places you can put a const (constant)
// restriction on a function definition line.
// const int returnConstInt(const int value1) const
// {
// }
// in order of placement in the function definition line
// 1: cannot alter the returning value
// 2: cannot alter the passing value
// 3: cannot alter the values of "this" as being the class this

class constTest {
private :
int value;
public:
constTest() { value = 0;};

int returnIntConst(int passingValue) const;
};

// cannot alter any value for the class variables e.g. value in this case.
// of course you could do a const_cast.. which takes off the constant (const) type
int constTest::returnIntConst(int passingValue) const
{
// cannot alter any value inside the function
// assignment of data-member

Pointers and references – part 2

As a follow on from the part 1 – pointers and references – this tutorial is all about how to pass pointers and references, with usage in functions.

As shown in the previous tutorial, a pointer is just a point to another memory location where the data is actually stored and a reference/address is the address (memory) location of a variable. e.g.

int *pInt= NULL;
int intValue = 10;
pInt = &intValue;

Here the pointer (*pInt) is first set to NULL, to point to no where in memory because it may have a rogue data in there and you would not want that. Then the intValue variables is set to 10 and then pInt value is set to the memory (address/reference) location of intValue.

When passing a parameter to a normal function you are just passing a copy of the value and not the actual variable being passed, so that if you make any alternations to that parameter variable is it not reflected back into the variable that was actual passed. I have included code at the bottom with the output that displays the memory locations of the local (function variables parameters) and the parameters passed and you can see that the memory location is different in the standard copy-value function (normalReturnMethod).

So for a coding example

int normalReturnMethod(int value)
{
    value = value +2;
    return (value);
}
 
int intValue = 10;
 
int newValue = normalReturnMethod(intValue);
cout << "new Value :  " << newValue << " intValue  : " << intValue;

and the output would be

new Value = 12 int Value : 10

Because even though in the function we are incrementing the variable value, it has not direction relationship with the intValue that was passed to it.

But if you did a pointer (*) in the parameters of the function, then the actual variable memory location is passed and not just a copy of the variable, in which case you can alter the variable.

For example in code

void pointerReturnMethod(int *pValue)
{
    // increment the value pointed to in the pValue parameter
    *pValue +=2;
}
int intValue = 10;
pointerReturnMethod(&intValue);
cout << "intValue = " << intValue;

and the output would be

intValue = 12

Because the function is talking to the parameter variable passed, instead of just a copy and you can do anything on that parameter as you would normally.

The other method is by passing a reference to the function instead of a address (memory) location or copy-of-value, this one is slightly more fun, because since you do not alter the way that you knowing are passing the variable e.g. passing in the memory location with the &, then you could think it is just the copy-of-value function and it may alter the passing variable as well, which really is not a good thing.

Code example

void referenceReturnMethod(int &fValue)
{
    fValue +=4;
}
 
int intValue = 10;
referenceReturnMethod(intValue);
cout << "intValue = " << intValue;

and the output would be

intValue = 14;

which if you was not wanting to pass the reference to the variable to be “worked on” as such, then you may hit some problems with debugging and start to wonder why the variable was alter when passed to a function.

Here is some more code that you can compile up and see what is happening. have fun.!!

#include <iostream>
 
using namespace std;
 
int normalReturnMethod(int value)
{
    cout << "normal Return Method memory location " << &value << endl;
    return (value + 2);
}
 
// pass in the pointer to a variable, the pointer (*)value is the same place 
// instead of a copy as normalReturnMethod parameter
void pointerReturnMethod(int *pValue)
{
    // increment the value pointed to in the pValue parameter
    *pValue +=2;
    cout << "pointer Return Method memory location  " << pValue << endl;
}
 
// pass in the reference to the method in the parameter, the reference is 
// a reference point to the passed in variable e.g. same place.
void referenceReturnMethod(int &fValue)
{
    fValue +=4;
    cout << "reference Return Method memory location " << &fValue << endl;
}
 
int main()
{
    // the standard way to update a value is to return a value
    // this is called the copy-variable way - it copies the value from the passing parameter to the function parameter
    int returnValue = normalReturnMethod(10);
    cout << "Hex value of memory place of returnValue " << &returnValue << endl;
    cout << "The new interger value " << returnValue << endl;
 
    // but if you pass the reference of variable &, this will alter the actually variable instead of needing to 
    // pass the variable back in the return type. - it passes a memory location reference
    pointerReturnMethod(&returnValue);
    // the returnValue has been altered.
    cout << "The new interger value " << returnValue << endl;
 
    referenceReturnMethod(returnValue);
    cout << "The returnvalue updated " << returnValue << endl;
    cout << "The memory address of the reference/pointer functions are the same as the returnValue hex value"<< endl;  
    cout << endl  << endl;
 
    int *valuePointer = &returnValue;
    // the find out the difference * and & here are the values
    cout << "The Hex value of memory place for returnValue and the VALUE of the memory place for the pointer are the same"<< endl;
    cout << "The value of the value pointer " << valuePointer << endl;
    cout << "Hex value of memory place of returnValue " << &returnValue << endl;
    cout << "The actually memory place of the valuepointer " << &valuePointer << " and the POINTED value " << *valuePointer << endl;
    cout << "And of course the valuepointer is the same, because it is pointing to the same place " << *valuePointer << endl;
 
 
    // the pointer (*) is the pointed to memory location. e.g. int value=10 could be a memory location that is pointed to
    // the reference (&) is the memory address of the variable
    // so for a pointer you need to set the memory location of a variable to its value, which in turn its 
    // pointed value is the variable, but its address/reference (&) is always the same becaues that is the place where
    // the pointer variable is setup, but the value (the memory location) is what alters.
    return 0;
}

and my test outputs would be, of course your memory locations will be different.

normal Return Method memory location 0x7fff34d8d1bc
Hex value of memory place of returnValue 0x7fff34d8d1dc
The new interger value 12
pointer Return Method memory location  0x7fff34d8d1dc
The new interger value 14
reference Return Method memory location 0x7fff34d8d1dc
The returnvalue updated 18
The memory address of the reference/pointer functions are the same as the returnValue hex value
 
 
The Hex value of memory place for returnValue and the VALUE of the memory place for the pointer are the same
The value of the value pointer 0x7fff34d8d1dc
Hex value of memory place of returnValue 0x7fff34d8d1dc
The actually memory place of the valuepointer 0x7fff34d8d1d0 and the POINTED value 18
And of course the valuepointer is the same, because it is pointing to the same place 18

Function arguments – c++

There are sometimes that you want to pass more than a defined number of parameters to a function (arguments). Of course you can pass a array of parameters or just use a inbuilt stdarg.h library. This allows you to pass allot of arguments into a function, but without defining them at compile time.

For example if you want to add up a list of numbers and run time, but do not know how many to pass at the compile time then you define the function method as

int sumvalues(int numbersToBePassed, ...);

The important part is the “…”, you have to always pass in the first parameter at least, because at run time this parameter will tell the function how many additional parts to the function there will be.

Then to setup the argument list, you use the c++ library stdarg.h and this will include the function/methods that will allow this to happen.

To start with you will need to setup the argument list,

va_list args

This will setup the variable args to contain the list of additional arguments passed, then to setup where to start to pull arguments from, e.g. where the last parameter named at compile time will know, if the parameter list is like

int sumedvalues(int value1, int value2, int additionalValues, ...)

then the additionalValues is the last parameter that the compile time will know about, so to setup the pointer to the next parameter for the args variable

// for the above example
va_start(args, additionValues);
//for the code example
va_start(args, numbersToBePassed);

to pull out a argument you just need to use the va_arg function, its parameters are

va_arg(va_list, type);

where the va_list is the args variable and the type is the type that you want back, e.g. int or float.

To complete the argument list you need to end the argument pull by

va_end(va_list)

where again the va_list would be args in this example.

Here is some code that will demo the above as well.

#include <iostream>
#include <stdarg.h>
 
using namespace std;
 
int sumvalues(int numbersToBePassed, ...)
{
  int sumd =0;
  va_list args;
  va_start(args,numbersToBePassed);
 
  for (int i =0; i < numbersToBePassed; i++)
  {
    sumd +=va_arg(args,int);
  }
  va_end(args);
  return sumd;
}
 
int main()
{
  cout << "Add the values 5 4 3 5 together = " << sumvalues(4, 5,4,3,5) << endl;
  return 0;
}

With the output being

Add the values 5 4 3 5 together = 17