C++ Classes incliding Structures-Classes-Unions








Introduction to Classes

Classes (also known as composite data types) are a collection of different data types grouped together to form one new self-defined type. The variable types we have used so far have been primitive types because they are declared in a very simplified manner. Each variable represented an object in its whole ( i.e int car) but at times we want a group of values to be considered as one entity to represent an object (car). For example, we may need to use one or more data types to represent the car object. In such a situation we can group the different data types into one data type of our liking and then use it the same we have used other data types. In C++, there are three techniques of defining a new self-defined data type: a structure, a class, and a union.

Structures

A structure is an aggregate of data types that together form new self-defined data type. It is built using several types including the structs. We create a structure using a the struct keyword, followed by a name for the object and the body of the structure with a semicolon at the end. The naming of the struct must follow convetional rules of names in C++. To create a composite type at least one known data type should be used to declare a variable in the body of the structure. Below is an example of a car structure.

struct Car
{ 
               int NumberOfDoors;
               string CarName; 
};

A variable declared within the body of the structure is referred to as a member of that structure. In our example of a structure of a car above, variables NumberOfDoors and CarName are member variables of the Car structure. Members of the same structure must have different names but members of the different structures could share the name without any conflict. The structure above creates a new data type called Car we can now onwards use to declare variables as we did with other inbuilt types such int, char, string, double and others (i.e. Car name; or Car ItsDoors;). Below is a simple program that uses the above structure.

#include<iostream>
using namespace std;

struct Car
{ 
               int NumberOfDoors;
               string CarName; 
};

int main()
{
Car vehicle={4,"Honda"};
cout<<"The name of the vehicle is "
    <<vehicle.CarName<<" and it has "
    <<vehicle.NumberOfDoors<<" doors"<<endl;
return 0;
}


The name of the vehicle is Honda and it has 4 doors

Note the way we declared and initialed the variable vehicle. We used the type Car which we created with the struct key word instead of using the built-in types. We initialized the variable vehicle as soon as we declared it. The compiler is able determine which one is an int and a string using the variables we included in the structure. A digit is automatically interpreted as an int while whatever is included in quotation marks is considered as a string. To access the values members of structure we insert the dot (.) operator between the declared variable (vehicle) and the member variable. We could also have attached the declaration of the vehicle to structure itself just before the semicolon. See the example below

#include<iostream>
using namespace std;

struct Car
{ 
               int NumberOfDoors;
               string CarName; 

} vehicle={4,"Honda"};

int main()
{
cout<<"The name of the vehicle is "
    <<vehicle.CarName<<" and it has "
    <<vehicle.NumberOfDoors<<" doors"<<endl;
return 0;
}


Outpot:The name of the vehicle is Honda and it has 4 doors



Classes

A class is another technique of grouping built in data types to create a self-defined data type. It is similar to structure data type and only differs it members are defaulted to private while those of the structure are public. Members declared as variables in either a structure or class are called data members and if they are functions they are known as member functions.

In C++ access labels public, protected and private are used within classes to set access permissions for the members in that section of the class. Permission labels are to restrict access to member function that reside outside the class and for other classes. However a member function of a class has access and ability to modify all the data and other member function inside that class.

The labels can be in any order and can be used multiple times in a class declaration for cases where it is logical to have multiple groups of these types. An access label remains active until another access label is used to change the permissions. The default access for members depend on the key word used class or structure as highlighted below;

  • The members of a class declared with the keyword class are private by default. A class is inherited privately by default.
  • The members of a class declared with the keyword struct are public by default. A structure is inherited publicly by default.

Apart from these few differences, a class is written in the same way a structure is done. Data members and member functions can be written inside the body of the class. Once a class type has been created, it can be used normally as any other built in types. The variables declared with the class type are referred to as objects of that class. Note that self-created type of a class is actually the name of that class. If Car is the name of class then our new type is Car. We can use Car to declare its objects as we use inbuilt data types to declare variables. Let us continue further with our car example as follows;

class Car
{ 
               int NumberOfDoors;
               string CarName; 

} vehicle={4,"Honda"};

int main()
{
cout<<"The name of the vehicle is "
    <<vehicle.CarName<<" and it has "
   <<vehicle.NumberOfDoors<<" doors"<<endl;
return 0;
}

As you may notice, the above example is an exact replica of our previous example on structure, save for the change of the key word from struct to class. In other words, every rule applicable to the structure in terms of naming, the body, the member variables, the curly brackets also applies to the class. Of course as we indicated there are some differences that set the structure and the class apart.

Like in a structure, once a variable (data member) or a function (member function) is declared inside a class, it can accessed outside the class, either to change its value or to retrieve the value it holds. To access the member of a class outside of the class, type the name of the variable, followed by a period, and a name of the member to be accessed. For example, in our example above to access the CarName and NumberOfDoors member variable of the Car class we inserted the dot operator between the object vehicle and the class member names.

Members of a class can be initialized either individually or as a whole. We first access the member of a class and then and assign it a value using C++ appropriate rules. A numeric type is assigned a number, a char type-character in single-quotes, a type bool- true or false, a string type-value in double-quotes and if it is an array of character we use the strcpy() function to copy a value into it.

To initialize members of the class as a whole, we type the name of the object/variable followed by the assignment operator, followed by a list of desired values of the variables separated by a comma and enclosed in curly brackets. If you initialize as a whole, the list of values must follow the order of the declared member variables of the class and none of the members of the class should be another class. When dealing with a class passing as whole will work if the members are declared public. For example, no member variable should have been declared as string. For example

#include<iostream>:
#include <string>
using namespace std;

class Car

{
public:
    char     Make[40];  //[40] maximum number of characters to hold 

    int      NumOfSeats ;

    bool     IsOfLHD;

};



int main( )

{

Car impsum = { "Toyota", 7, true};
cout<<" The impsum is a "<<impsum.Make<<", it has "<<impsum.NumOfSeats<<" seats and it is "<<impsum.IsOfLHD<<", its a left hand drive car" <<endl;

return 0;
}
Ouput: The impsum is a Toyota, it has 7 seats and it is true, its a left hand drive car

Note: The program will not compile if it contains two variables with the name of one variable being the same as the name of the class. If same names must be used, use the key class (or struct for a structure) at an instance a class (when an object is being declared). This specifies to the compiler that the created object/variable is of a class type and not the other variable.

The example below utilizes the concept of member data, member function and private and public access privileges

#include<iostream>
#include <string>
using namespace std;

struct Car
{ 
   
public:              //members key word “private” are private-accessible                       
                     //by only members of this class 

void setNameandDoors(int doors, string name  )
  {
     NumberOfDoors=doors; CarName=name;
   }

void displayVehicle()
   {
         cout<<"The vehicle is a "<<CarName<<" and it has "
         <<NumberOfDoors<<" doors"<<endl;
    }

 private:             //members below key word “private” are private-accessible                       
                     //by only members of this class 

                string CarName;
               int NumberOfDoors;

};

// This global variable below has the same name as the Car object in main()
string vehicle="Ninsan"; 

void printVehicle()
 {
   cout<<"The second vehicle whose type is not declared in the Car class is a "<<vehicle<<endl;
 }

int main()
{
string Name="Toyota";
int Doors=4;

/*we use the key word class because variable vehicle is already declared 
as a string type*/

struct Car vehicle;     //instatiation of object vehicle of the class Car
   
vehicle.setNameandDoors(Doors,Name);
vehicle.displayVehicle();

printVehicle();

return 0;
}
Output: The vehicle is a Toyota and it has 4 doors The second vehicle whose type is not declared in the Car class is a Ninsan

In the example above we declared a class type known as Car and in mian () we also instantiated an object (i.e., a variable) of this class called vehicle. The Car class contains four members: two data members of type one of int (member NumberOfDoors) and second of a string type (member CarName ) with private access and two member functions with public access setNameandDoors and displayVehicle(), for which we included their definition inside the class although it is possible to define from outside as we shall see.

Member functions have direct access and ability to modify data members of their class. This is why setNameandDoors is able to access and modify(by way of initializing them) data members CarName and NumberOfDoors. Member displayVehicle access the same data members and display their values. Take note that a member a member of a class cannot be initialized inside of the class. It has to be initialized outside of the class.

Global Objects

At times we need to access an object/variable within different parts of the program. Such variables need to be defined outside the functions so as to enable accessibility to more than one function. As we are aware C++ programs are executed and compiled from top-down basis. As such a variable, object or function declared globally can be seen only by functions under it.

C++ allows for first declaration of the name of the class even if its members are not yet defined. This technique is referred to as forward definition. In this case, you specify only the type (struct or class) and the name of the class. This allows you to do some tasks that don't require the members of the class. However you cannot use members of the class unless they are defined first.

Members of a class can be initialized either individually or as a whole. We first access the member of a class and then and assign it a value using C++ appropriate rules. A numeric type is assigned a number, a char type-character in single-quotes, a type bool- true or false, a string type-value in double-quotes and if it is an array of character we use the strcpy() function to copy a value into it. An object is initialized the same way we do for a variable.

Just type the name of the object variable followed by the assignment operator, followed by the desired values of the variables listed between an opening and a closing curly brackets. Here are the rules you must follow:

  • The list of values must follow the order of the declared member variables of the class
  • The values are separated with commas
  • None of the members of the class can be another class. For example, no member variable should have been declared as string

Static member variables

When an application starts, a compiler creates a copy of the member variable declared as static. This copy of static member variable is maintained by the compiler while the program is running. A static member is not part of the class object, rather the compiler creates and maintains a copy of the static member variable and makes available for all objects of the class.

A static member variable must be initialized at file cope by the class itself and not one of its instances because it is not part of an object. By default a static member is initialized to zero. To declare such a variable, precede it with the static keyword. Here is an example:

#include<iostream>
#include <string>
using namespace std;

class Car

{
public:
    
    int      Year;

    static bool sold;

};

bool Car::sold=true;



int main()

{

    Car vehicle;

     vehicle.Year=2009;
    

cout<<" Yes, it is "<<Car::sold<<", all vehicles manufactured in "<<vehicle.Year<<" have been sold"<<endl;
return 0;
}
Output:Yes, it is true, all vehicles manufactured in 2009 have been sold

Notice the way we accessed a static member variable sold. Remember that a static is not part of a particular object of the class, in this case vehicle. That is why we access differently. To assign a value to a static member variable, we access it using the name of the class followed by the "::" operator and then the name of static variable.

To initialize a static member variable, outside of the class, enter its data type, followed by the; name of the class, access operator (::), name of the member variable, assignment operator, and a value in this order. Follow the example below.

	#include<iostream>
	#include <string>
	using namespace std;

	class Car

	{

    
    		int      Year;

    		static bool sold;

	};

	bool Car::sold=true;



	int main()

	{

   		 Car vehicle;


     		Vehicle.year=2009;
    

		cout<<” Yes, it is “<<Car::sold<<”, all vehicles manufactured in “<<vehicle.year<<” have been sold”<<endl;
	return 0;
	}

You may have noticed that static members operate like global variables and you are wondering why not then declare them as such. The reason is that including the variable in a class, ensures that it will be accessible to only class objects.

Member functions can also be defined to be static. Static member functions are accessible even when the class is not instantiated. Static member functions are useful for defining call-back (when that pointer is used to call the function it points to) routines whose parameter lists are predetermined and outside the control of the programmer. We cover call back routines later when we coverpointers. They do not receive an implicit argument and hence cannot refer to this

#include<iostream>
#include<string>
using namespace std;

class Car

{

    
    int      Year;

public:
  
 static void SaleStatus(bool sold)// a static member function
    {
      if(sold==true)
     cout<<"Yes, we have in stock ";
     else 
     cout<<"No, we do not have in stock ";
    }

 
      int ReturnYear(int y)
        {
          Year=y;
        return Year;
        }
};


int main()

{

    Car vehicle;
    int y=2009;     

     bool sold=true;

Car::SaleStatus(sold); // a static function without 
                       //instantiating the Car class object

cout<<"vehicles manufactured in "
<<vehicle.ReturnYear(y) <<endl;

return 0;
}
Points to remember on static member function.
  • A static member function can only access static member data, static member functions and data and functions outside the class
  • A static member function cannot be declared as virtual
  • All objects of the class share the variables in static functions.
    .
  • A static member function can be called, even when a class is not instantiated.
Main differences between a static member function and non-static member functions
  • A static member function can access only static member data, static member functions and data and functions outside the class. A non-static member function can access all including the static data member.

  • A static member function can be called, even when a class is not instantiated, a non-static member function can be called only after instantiating the class as an object.

  • A static member function cannot be declared virtual, whereas a non-static member functions can be declared as virtual

  • A static member function cannot have access to the 'this' pointer of the class.

References to a member of the class or its object

As done for variables of primitive types, you can create a reference to a class object using a declared variable. A reference is an alias name i.e. another name by which it can be called. A reference must be initialized with existing object. A reference to an object is initialized once and cannot be reinitialized with another object.

A class data member can be defined as reference. As with data member constants, a data member reference cannot be initialized using the same syntax as for other references: A reference member is initialized through a member initialization list.

#include<iostream>
#include<string>
using namespace std;

class Car

{
bool status;
bool &sold;

public:
    Car(bool s):sold(status){status=s;}
    int      Year;

   bool getstatus(){ return sold;}
};


int main()

{
Car Motorcar (true);
    Car &vehicle=Motorcar;  //vehicle is a reference to Motorcar

     vehicle.Year=2009;
    

cout<<" Yes, it is "<<vehicle.getstatus()
<<", all vehicles manufactured in "
<<vehicle.Year<<" have been sold"
<<endl;

return 0;
}

output:

Yes, it is true, all vehicles manufactured in 2009 have been sold
PREV:Introduction to Arrays NEXT:Constructors and Distructors