Topic : C++ tutorial for C users
Author : Eric Brasseur
Page : << Previous 4  Next >>
Go to page :


                                      // the [] would deallocate the
                                      // memory zone without destructing
                                      // each of the 15 instances. That
                                      // would cause memory leakage.

   int n = 30;

   d = new double[n];                 // new can be used to allocate an
                                      // array of random size.
   for (int i = 0; i < n; i++)
   {
      d[i] = i;
   }

   delete [] d;


   char *s;

   s = new char[100];

   strcpy (s, "Hello!");

   cout << s << endl;

   delete [] s;

}



15
What is a class? Well, that's a struct yet with more possibilities. METHODS can be defined. They are C++ functions dedicated to the class. Here is an example of such a class definition:


#include <iostream.h>

class vector
{
public:

   double x;
   double y;

   double surface ()
   {
      double s;
      s = x * y;
      if (s < 0) s = -s;
      return s;
   }
};

void main(void)
{
   vector a;

   a.x = 3;
   a.y = 4;

   cout << "The surface of a: " << a.surface() << endl;
}



In the example above, a is an INSTANCE of the class "vector".
Just like a function, a method can be an overload of any C++ operator, have any number of parameters (yet one parameter is always implicit: the instance it acts upon), return any type of parameter, or return no parameter at all.

A method is allowed to change the variables of the instance it is acting upon:


#include <iostream.h>

class vector
{
public:

   double x;
   double y;

   vector its_oposite()
   {
      vector r;

      r.x = -x;
      r.y = -y;

      return r;
   }

   void be_oposited()
   {
      x = -x;
      y = -y;
   }

   void be_calculated (double a, double b, double c, double d)
   {
      x = a - c;
      y = b - d;
   }

   vector operator * (double a)
   {
      vector r;

      r.x = x * a;
      r.y = y * a;

      return r;
   }
};

void main (void)
{
   vector a, b;

   a.x = 3;
   b.y = 5;

   b = a.its_oposite();

   cout << "Vector a: " << a.x << ", " << a.y << endl;
   cout << "Vector b: " << b.x << ", " << b.y << endl;

   b.be_oposited();
   cout << "Vector b: " << b.x << ", " << b.y << endl;

   a.be_calculated (7, 8, 3, 2);
   cout << "Vector a: " << a.x << ", " << a.y << endl;

   a = b * 2;
   cout << "Vector a: " << a.x << ", " << a.y << endl;

   a = b.its_oposite() * 2;
   cout << "Vector a: " << a.x << ", " << a.y << endl;

   cout << "x of oposite of a: " << a.its_oposite().x << endl;
}


16
Very special and essential methods are the CONSTRUCTOR and DESTRUCTOR. They are automatically called whenever an instance of a class is created or destroyed (variable declaration, end of program, new, delete...).

The constructor will initialize the variables of the instance, do some calculation, allocate some memory for the instance, output some text... whatever is needed.

Here is an example of a class definition with two overloaded constructors:

#include <iostream.h>

class vector
{
public:

   double x;
   double y;

   vector ()                     // same name as class
   {
      x = 0;
      y = 0;
   }

   vector (double a, double b)
   {
      x = a;
      y = b;
   }

};

void main ()
{
   vector k;                     // vector () is called

   cout << "vector k: " << k.x << ", " << k.y << endl << endl;

   vector m (45, 2);             // vector (double, double) is called

   cout << "vector m: " << m.x << ", " << m.y << endl << endl;

   k = vector (23, 2);           // vector created, copied to k, then
erased

   cout << "vector k: " << k.x << ", " << k.y << endl << endl;
}



It is a good practice to try not to overload the constructors. Best is to declare only one constructor and give it default parameters wherever possible:


#include <iostream.h>

class vector
{
public:

   double x;
   double y;

   vector (double a = 0, double b = 0)
   {
      x = a;
      y = b;
   }
};

void main ()
{
   vector k;
   cout << "vector k: " << k.x << ", " << k.y << endl << endl;

   vector m (45, 2);
   cout << "vector m: " << m.x << ", " << m.y << endl << endl;

   vector p (3);
   cout << "vector p: " << p.x << ", " << p.y << endl << endl;
}



The destructor is often not necessary. You can use it to do some calculation whenever an instance is destroyed or output some text for debugging. But if variables of the instance point towards some allocated memory then the role of the destructor is essential: it must free that memory! Here is an example of such an application:

#include <iostream.h>
#include <string.h>

class person
{
public:

   char *name;
   int age;

   person (char *n = "no name", int a = 0)
   {
      name = new char[100];                 // better than malloc!
      strcpy (name, n);
      age = a;
      cout << "Instance initialized, 100 bytes allocated" << endl;
   }

   ~person ()                               // The destructor
   {
      delete name;                          // instead of free!
      cout << "Instance going to be deleted, 100 bytes freed" << endl;
   }
};

void main ()
{
    cout << "Hello!" << endl


Page : << Previous 4  Next >>