5, C + + classes & objects

Posted by jmartinez on Fri, 17 Dec 2021 08:28:27 +0100

C + + adds object-oriented programming on the basis of C language, and C + + supports object-oriented programming. Class is the core feature of C + +, which is usually called user-defined type.

Class is used to specify the form of an object. It contains data representation and methods for processing data. The data and methods in a class are called members of the class. Functions in a class are called members of the class.

1, C + + class definition

Defining a class is essentially a blueprint for defining a data type. This does not actually define any data, but it defines what the class name means, that is, it defines what the class object includes and what operations can be performed on this object.
A class definition starts with the keyword class, followed by the name of the class. The body of the class is contained in a pair of curly braces. Class definition must be followed by a semicolon or a declaration list. For example, we use the keyword class to define the Box data type, as shown below:

class Box
{
   public:
      double length;   // Length of box
      double breadth;  // Width of box
      double height;   // Height of box
};

The keyword public determines the access properties of class members. Within the scope of a class object, public members are accessible outside the class. You can also specify the members of the class as private or protected, which we will explain later.

2, Defining C + + objects

Classes provide a blueprint for objects, so basically, objects are created based on classes. Declaring objects of classes is like declaring variables of basic types. The following statement declares two objects of class Box:

Box Box1;          // Declare Box1, type Box
Box Box2;          // Declare Box2, type Box

Objects Box1 and Box2 have their own data members.
Access data members
Class can use the direct member access operator To access.

#include <iostream>
 
using namespace std;
 
class Box
{
   public:
      double length;   // length
      double breadth;  // width
      double height;   // height
      // Member function declaration
      double get(void);
      void set( double len, double bre, double hei );
};
// Member function definition
double Box::get(void)
{
    return length * breadth * height;
}
 
void Box::set( double len, double bre, double hei)
{
    length = len;
    breadth = bre;
    height = hei;
}
int main( )
{
   Box Box1;        // Declare Box1, type Box
   Box Box2;        // Declare Box2, type Box
   Box Box3;        // Declare Box3, type Box
   double volume = 0.0;     // For storage volume
 
   // box 1 details
   Box1.height = 5.0; 
   Box1.length = 6.0; 
   Box1.breadth = 7.0;
 
   // box 2 details
   Box2.height = 10.0;
   Box2.length = 12.0;
   Box2.breadth = 13.0;
 
   // Volume of box 1
   volume = Box1.height * Box1.length * Box1.breadth;
   cout << "Box1 Volume of:" << volume <<endl;
 
   // Volume of box 2
   volume = Box2.height * Box2.length * Box2.breadth;
   cout << "Box2 Volume of:" << volume <<endl;
 
 
   // box 3 details
   Box3.set(16.0, 8.0, 12.0); 
   volume = Box3.get(); 
   cout << "Box3 Volume of:" << volume <<endl;
   return 0;
}

Operation results
Volume of Box1: 210
Box2 volume: 1560
Volume of Box3: 1536

It should be noted that private members and protected members cannot use the direct member access operator () To access directly. We will learn how to access private and protected members in subsequent tutorials.

3, Class & object details

So far, we have a basic understanding of C + + classes and objects. The following list also lists some other concepts related to C + + classes and objects.

conceptdescribe
Class member functionClass member functions refer to those functions that write definitions and prototypes inside the class definition, just like other variables in the class definition.
Class access modifierClass members can be defined as public, private, or protected. It is defined as private by default.
Constructor & destructorClass constructor is a special function that is called when a new object is created. Class destructor is also a special function that is called when the created object is deleted.
C + + copy constructorCopy constructor is a special constructor. When creating an object, it uses the previously created object in the same class to initialize the newly created object.
C + + friend functionFriend functions can access private and protected members of a class.
C + + inline functionWith inline functions, the compiler attempts to extend the code in the function body where the function is called.
this pointer in C + +Each object has a special pointer this, which points to the object itself.
Pointer to class in C + +Pointers to classes are like pointers to structures. In fact, a class can be seen as a structure with functions.
Static members of C + + classesBoth data members and function members of a class can be declared static.

1. Class member function

Class member functions refer to those functions that write definitions and prototypes inside the class definition, just like other variables in the class definition. Class member function is a member of a class. It can operate any object of the class and access all members in the object.

Let's take a look at the previously defined class Box. Now we want to use the member function to access the members of the class instead of directly accessing the members of these classes:

class Box
{
   public:
      double length;         // length
      double breadth;        // width
      double height;         // height
      double getVolume(void);// Return volume
};

Member functions can be defined inside the class definition or by using the range resolution operator:: alone. Member functions defined in the class definition declare the function inline, even if the inline identifier is not used.
So you can define the getVolume() function as follows:

class Box
{
   public:
      double length;      // length
      double breadth;     // width
      double height;      // height
   
      double getVolume(void)
      {
         return length * breadth * height;
      }
};

You can also define this function outside the class using the range resolution operator:: as follows:

double Box::getVolume(void)
{
    return length * breadth * height;
}

Here, it should be emphasized that the class name must be used before the (::) operator. The member function is called by using the dot operator (.) on the object, In this way, it can manipulate the data related to the object, as follows:

Box myBox;          // Create an object
 
myBox.getVolume();  // Call the member function of the object

Example:

#include <iostream>
 
using namespace std;
 
class Box
{
   public:
      double length;         // length
      double breadth;        // width
      double height;         // height
 
      // Member function declaration
      double getVolume(void);
      void setLength( double len );
      void setBreadth( double bre );
      void setHeight( double hei );
};
 
// Member function definition
double Box::getVolume(void)
{
    return length * breadth * height;
}
 
void Box::setLength( double len )
{
    length = len;
}
 
void Box::setBreadth( double bre )
{
    breadth = bre;
}
 
void Box::setHeight( double hei )
{
    height = hei;
}
 
// Main function of program
int main( )
{
   Box Box1;                // Declare Box1, type Box
   Box Box2;                // Declare Box2, type Box
   double volume = 0.0;     // For storage volume
 
   // box 1 details
   Box1.setLength(6.0); 
   Box1.setBreadth(7.0); 
   Box1.setHeight(5.0);
 
   // box 2 details
   Box2.setLength(12.0); 
   Box2.setBreadth(13.0); 
   Box2.setHeight(10.0);
 
   // Volume of box 1
   volume = Box1.getVolume();
   cout << "Box1 Volume of:" << volume <<endl;
 
   // Volume of box 2
   volume = Box2.getVolume();
   cout << "Box2 Volume of:" << volume <<endl;
   return 0;
}

Operation results
Volume of Box1: 210
Box2 volume: 1560

2. Class access modifier

Data encapsulation is an important feature of object-oriented programming. It prevents functions from directly accessing internal members of class types. The access restrictions of class members are specified by marking each region public, private and protected within the class body. The keywords public, private and protected are called access modifiers.

A class can have multiple public, protected, or private tag areas. Each markup region is valid before the beginning of the next markup region or before the class body end closing bracket is encountered. The default access modifier for members and classes is private.

class Base {
 
   public:
 
  // public members 
 
   protected:
 
  // Protected member
 
   private:
 
  // Private member
 
};

public member

Public members are accessible outside the class in the program. You can set and get the value of a public variable without using any member functions, as shown below:

#include <iostream>
 
using namespace std;
 
class Line
{
   public:
      double length;
      void setLength( double len );
      double getLength( void );
};
 
// Member function definition
double Line::getLength(void)
{
    return length ;
}
 
void Line::setLength( double len )
{
    length = len;
}
 
// Main function of program
int main( )
{
   Line line;
 
   // Set length
   line.setLength(6.0); 
   cout << "Length of line : " << line.getLength() <<endl;
 
   // Set length without member function
   line.length = 10.0; // OK: because length is public
   cout << "Length of line : " << line.length <<endl;
   return 0;
}

Operation results
Length of line : 6
Length of line : 10

private member

Private member variables or functions are inaccessible or even viewable outside the class. Only classes and friend functions can access private members.

By default, all members of a class are private. For example, in the following class, width is a private member, which means that if you do not use any access modifiers, the members of the class will be assumed to be private members:

class Box
{
   double width;
   public:
      double length;
      void setWidth( double wid );
      double getWidth( void );
};

In practice, we usually define data in the private area and relevant functions in the public area, so that these functions can also be called outside the class, as shown below:

#include <iostream>
 
using namespace std;
 
class Box
{
   public:
      double length;
      void setWidth( double wid );
      double getWidth( void );
 
   private:
      double width;
};
 
// Member function definition
double Box::getWidth(void)
{
    return width ;
}
 
void Box::setWidth( double wid )
{
    width = wid;
}
 
// Main function of program
int main( )
{
   Box box;
 
   // Set length without member function
   box.length = 10.0; // OK: because length is public
   cout << "Length of box : " << box.length <<endl;
 
   // Set width without member function
   // box.width = 10.0; // Error: because width is private
   box.setWidth(10.0);  // Set width using member function
   cout << "Width of box : " << box.getWidth() <<endl;
 
   return 0;
}

Operation results
Length of box : 10
Width of box : 10

protected member

Protected member variables or functions are very similar to private members, but with one difference, protected members are accessible in derived classes (i.e. subclasses).

In the next chapter, you will learn about derived classes and inheritance. Now you can see that in the following example, we derived a subclass smallBox from the parent class Box.

The following example is similar to the previous example, where the width member can be accessed by any member function of the derived class smallBox.

#include <iostream>
using namespace std;
 
class Box
{
   protected:
      double width;
};
 
class SmallBox:Box // SmallBox is a derived class
{
   public:
      void setSmallWidth( double wid );
      double getSmallWidth( void );
};
 
// Member functions of subclasses
double SmallBox::getSmallWidth(void)
{
    return width ;
}
 
void SmallBox::setSmallWidth( double wid )
{
    width = wid;
}
 
// Main function of program
int main( )
{
   SmallBox box;
 
   // Set width using member function
   box.setSmallWidth(5.0);
   cout << "Width of box : "<< box.getSmallWidth() << endl;
 
   return 0;
}

Operation results
Width of box : 5

Characteristics in inheritance

There are three inheritance methods: public, protected and private, which change the access properties of base class members accordingly.

♦ 1.public inheritance: the access properties of public, protected and private members of the base class become public, protected and private respectively in the derived class

♦ 2.protected inheritance: the access properties of public, protected and private members of the base class become protected, protected and private respectively in the derived class

♦ 3.private inheritance: the access properties of public members, protected members and private members of the base class become private, private and private respectively in the derived class

However, no matter which inheritance method, the above two points have not changed:

♦ 1.private members can only be accessed by members of this class (within the class) and friends, not by derived classes;

♦ 2.protected members can be accessed by derived classes.

public inheritance

#include<iostream>
#include<assert.h>
using namespace std;
 
class A{
public:
  int a;
  A(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //correct
    cout << a1 << endl;   //correct
    cout << a2 << endl;   //correct
    cout << a3 << endl;   //correct
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};
class B : public A{
public:
  int a;
  B(int i){
    A();
    a = i;
  }
  void fun(){
    cout << a << endl;       //Correct, public member
    cout << a1 << endl;       //Yes, the public member of the base class is still a public member in the derived class.
    cout << a2 << endl;       //Correctly, the protected member of the base class is still protected in the derived class and can be accessed by the derived class.
    cout << a3 << endl;       //Error, private member of base class cannot be accessed by derived class.
  }
};
int main(){
  B b(10);
  cout << b.a << endl;
  cout << b.a1 << endl;   //correct
  cout << b.a2 << endl;   //Error, protected member cannot be accessed outside class
  cout << b.a3 << endl;   //Error, private member cannot be accessed outside class
  system("pause");
  return 0;
}

protected inheritance

#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
  int a;
  A(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //correct
    cout << a1 << endl;   //correct
    cout << a2 << endl;   //correct
    cout << a3 << endl;   //correct
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};
class B : protected A{
public:
  int a;
  B(int i){
    A();
    a = i;
  }
  void fun(){
    cout << a << endl;       //Correct, public member.
    cout << a1 << endl;       //Correctly, the public member of the base class becomes protected in the derived class and can be accessed by the derived class.
    cout << a2 << endl;       //Correctly, the protected member of the base class is still protected in the derived class and can be accessed by the derived class.
    cout << a3 << endl;       //Error, private member of base class cannot be accessed by derived class.
  }
};
int main(){
  B b(10);
  cout << b.a << endl;       //correct. public member
  cout << b.a1 << endl;      //Error, protected members cannot be accessed outside the class.
  cout << b.a2 << endl;      //Error, protected members cannot be accessed outside the class.
  cout << b.a3 << endl;      //Error, private members cannot be accessed outside the class.
  system("pause");
  return 0;
}

private inheritance

#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
  int a;
  A(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //correct
    cout << a1 << endl;   //correct
    cout << a2 << endl;   //correct
    cout << a3 << endl;   //correct
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};
class B : private A{
public:
  int a;
  B(int i){
    A();
    a = i;
  }
  void fun(){
    cout << a << endl;       //Correct, public member.
    cout << a1 << endl;       //Correctly, the public member of the base class becomes private in the derived class and can be accessed by the derived class.
    cout << a2 << endl;       //Correctly, the protected member of the base class becomes private in the derived class and can be accessed by the derived class.
    cout << a3 << endl;       //Error, private member of base class cannot be accessed by derived class.
  }
};
int main(){
  B b(10);
  cout << b.a << endl;       //correct. public member
  cout << b.a1 << endl;      //Error, private members cannot be accessed outside the class.
  cout << b.a2 << endl;      //Error, private members cannot be accessed outside the class.
  cout << b.a3 << endl;      //Error, private members cannot be accessed outside the class.
  system("pause");
  return 0;
}

3. Constructor & destructor

1. Class constructor

The constructor of a class is a special member function of a class, which is executed every time a new object of the class is created.

The constructor name is exactly the same as the class name, and will not return any type, nor will it return void. Constructors can be used to set initial values for some member variables.

The following example helps to better understand the concept of constructor:

#include <iostream>
 
using namespace std;
 
class Line
{
   public:
      void setLength( double len );
      double getLength( void );
      Line();  // This is a constructor
 
   private:
      double length;
};
 
// Member function definitions, including constructors
Line::Line(void)
{
    cout << "Object is being created" << endl;
}
 
void Line::setLength( double len )
{
    length = len;
}
 
double Line::getLength( void )
{
    return length;
}
// Main function of program
int main( )
{
   Line line;
 
   // Set length
   line.setLength(6.0); 
   cout << "Length of line : " << line.getLength() <<endl;
 
   return 0;
}

Operation results
Object is being created
Length of line : 6

2. Constructor with parameters

The default constructor does not have any parameters, but it can also take parameters if necessary. In this way, the object will be assigned an initial value when it is created, as shown in the following example:

#include <iostream>
 
using namespace std;
 
class Line
{
   public:
      void setLength( double len );
      double getLength( void );
      Line(double len);  // This is a constructor
 
   private:
      double length;
};
 
// Member function definitions, including constructors
Line::Line( double len)
{
    cout << "Object is being created, length = " << len << endl;
    length = len;
}
 
void Line::setLength( double len )
{
    length = len;
}
 
double Line::getLength( void )
{
    return length;
}
// Main function of program
int main( )
{
   Line line(10.0);
 
   // Gets the length of the default setting
   cout << "Length of line : " << line.getLength() <<endl;
   // Set the length again
   line.setLength(6.0); 
   cout << "Length of line : " << line.getLength() <<endl;
 
   return 0;
}

Operation results
Object is being created, length = 10
Length of line : 10
Length of line : 6

3. Use the initialization list to initialize fields

Use the initialization list to initialize fields:

Line::Line( double len): length(len)
{
    cout << "Object is being created, length = " << len << endl;
}

The above syntax is equivalent to the following syntax:

Line::Line( double len)
{
    length = len;
    cout << "Object is being created, length = " << len << endl;
}

Suppose there is a class C with multiple fields X, Y, Z, etc. that need to be initialized. Similarly, you can use the above syntax. You only need to separate different fields with commas, as shown below:

C::C( double a, double b, double c): X(a), Y(b), Z(c)
{
  ....
}

4. Class destructor

Class destructor is a special member function of a class, which is executed every time the created object is deleted.

The name of the destructor is exactly the same as that of the class, except that it is prefixed with a tilde (~), which will not return any value or take any parameters. The destructor helps to release resources before jumping out of the program (such as closing files, freeing memory, etc.).

The following examples help to better analyze the concept of constructors:

#include <iostream>
 
using namespace std;
 
class Line
{
   public:
      void setLength( double len );
      double getLength( void );
      Line();   // This is a constructor declaration
      ~Line();  // This is the destructor declaration
 
   private:
      double length;
};
 
// Member function definitions, including constructors
Line::Line(void)
{
    cout << "Object is being created" << endl;
}
Line::~Line(void)
{
    cout << "Object is being deleted" << endl;
}
 
void Line::setLength( double len )
{
    length = len;
}
 
double Line::getLength( void )
{
    return length;
}
// Main function of program
int main( )
{
   Line line;
 
   // Set length
   line.setLength(6.0); 
   cout << "Length of line : " << line.getLength() <<endl;
 
   retur

Operation results
Object is being created
Length of line : 6
Object is being deleted

4.C + + copy constructor

Copy constructor is a special constructor. When creating an object, it uses the previously created object in the same class to initialize the newly created object. Copy constructors are typically used to:

  • Initialize the newly created object by using another object of the same type.
  • The copy object passes it as an argument to the function.
  • Copy the object and return it from the function.

If there is no copy constructor defined in the class, the compiler will define one by itself. If a class has pointer variables and dynamic memory allocation, it must have a copy constructor. The most common forms of copy constructors are as follows:

classname (const classname &obj) {
   // Body of constructor
}

Here, obj is an object reference that is used to initialize another object.

#include <iostream>
 
using namespace std;
 
class Line
{
   public:
      int getLength( void );
      Line( int len );             // Simple constructor
      Line( const Line &obj);      // copy constructor 
      ~Line();                     // Destructor
 
   private:
      int *ptr;
};
 
// Member function definitions, including constructors
Line::Line(int len)
{
    cout << "Call constructor" << endl;
    // Allocate memory for pointers
    ptr = new int;//Open up a memory space of the size of int in the heap and point the pointer ptr to it
//The memory space in the heap is available throughout the program until it is freed by delete.
    *ptr = len;
}
 
Line::Line(const Line &obj)
{
    cout << "Call the copy constructor and set the pointer ptr Allocate memory" << endl;
    ptr = new int;
    *ptr = *obj.ptr; // Copy value
}
 
Line::~Line(void)
{
    cout << "Free memory" << endl;
    delete ptr;
}
int Line::getLength( void )
{
    return *ptr;
}
 
void display(Line obj)
{
   cout << "line size : " << obj.getLength() <<endl;
}
 
// Main function of program
int main( )
{
   Line line(10);
 
   display(line);
 
   return 0;
}

Operation results:
Call constructor
Call the copy constructor and allocate memory for the pointer ptr
line size: 10
Free memory
Free memory

The following example slightly modifies the above example and initializes the newly created object by using the existing object of the same type:

#include <iostream>
 
using namespace std;
 
class Line
{
   public:
      int getLength( void );
      Line( int len );             // Simple constructor
      Line( const Line &obj);      // copy constructor 
      ~Line();                     // Destructor
 
   private:
      int *ptr;
};
 
// Member function definitions, including constructors
Line::Line(int len)
{
    cout << "Call constructor" << endl;
    // Allocate memory for pointers
    ptr = new int;
    *ptr = len;
}
 
Line::Line(const Line &obj)
{
    cout << "Call the copy constructor and set the pointer ptr Allocate memory" << endl;
    ptr = new int;
    *ptr = *obj.ptr; // Copy value
}
 
Line::~Line(void)
{
    cout << "Free memory" << endl;
    delete ptr;
}
int Line::getLength( void )
{
    return *ptr;
}
 
void display(Line obj)
{
   cout << "line size : " << obj.getLength() <<endl;
}
 
// Main function of program
int main( )
{
   Line line1(10);
 
   Line line2 = line1; // The copy constructor is also called here
 
   display(line1);
   display(line2);
 
   return 0;
}

Operation results:
Call constructor
Call the copy constructor and allocate memory for the pointer ptr
Call the copy constructor and allocate memory for the pointer ptr
line size: 10
Free memory
Call the copy constructor and allocate memory for the pointer ptr
line size: 10
Free memory
Free memory
Free memory

5.C + + friend functions

The friend function of a class is defined outside the class, but has access to all private and protected members of the class. Although the prototype of the friend function has appeared in the definition of the class, the friend function is not a member function.

A friend can be a function, which is called a friend function; A friend can also be a class, which is called a friend class. In this case, the whole class and all its members are friends.

If you want to declare a function as a friend of a class, you need to use the keyword friend before the function prototype in the class definition, as shown below:

class Box
{
   double width;
public:
   double length;
   friend void printWidth( Box box );
   void setWidth( double wid );
};

To declare all member functions of class ClassTwo as friends of class ClassOne, you need to place the following declaration in the definition of class ClassOne:

friend class ClassTwo;

Example:

#include <iostream>
 
using namespace std;
 
class Box
{
   double width;
public:
   friend void printWidth( Box box );
   void setWidth( double wid );
};
 
// Member function definition
void Box::setWidth( double wid )
{
    width = wid;
}
 
// Note that printWidth() is not a member function of any class
void printWidth( Box box )
{
   /* Because printWidth() is a friend of Box, it can directly access any member of the class */
   cout << "Width of box : " << box.width <<endl;
}
 
// Main function of program
int main( )
{
   Box box;
 
   // Set width using member function
   box.setWidth(10.0);
   
   // Output width using friend function
   printWidth( box );
 
   return 0;
}

Operation results:
Width of box : 10

6.C + + inline function

C + + inline functions are commonly used with classes. If a function is inline, the compiler will place a copy of the code of the function where the function is called at compile time.

Any modification to the inline function requires recompilation of all clients of the function, because the compiler needs to replace all the code once, otherwise the old function will continue to be used.

If you want to define a function as an inline function, you need to place the keyword inline in front of the function name. You need to define the function before calling the function. If more than one line of functions is defined, the compiler ignores the inline qualifier.

The functions defined in the class definition are all inline functions, even if the inline specifier is not used.

The following is an example that uses an inline function to return the maximum of two numbers:

#include <iostream>
 
using namespace std;

inline int Max(int x, int y)
{
   return (x > y)? x : y;
}

// Main function of program
int main( )
{

   cout << "Max (20,10): " << Max(20,10) << endl;
   cout << "Max (0,200): " << Max(0,200) << endl;
   cout << "Max (100,1010): " << Max(100,1010) << endl;
   return 0;
}

Operation results:
Max (20,10): 20
Max (0,200): 200
Max (100,1010): 1010

7. this pointer in C + +

In C + +, each object can access its own address through the this pointer. The this pointer is an implicit argument to all member functions. Therefore, inside the member function, it can be used to point to the calling object.

The friend function does not have a this pointer because the friend is not a member of the class. Only member functions have this pointer.

The following example helps to better understand the concept of this pointer:

#include <iostream>
 
using namespace std;
 
class Box
{
   public:
      // Constructor definition
      Box(double l=2.0, double b=2.0, double h=2.0)
      {
         cout <<"Constructor called." << endl;
         length = l;
         breadth = b;
         height = h;
      }
      double Volume()
      {
         return length * breadth * height;
      }
      int compare(Box box)
      {
         return this->Volume() > box.Volume();
      }
   private:
      double length;     // Length of a box
      double breadth;    // Breadth of a box
      double height;     // Height of a box
};
 
int main(void)
{
   Box Box1(3.3, 1.2, 1.5);    // Declare box1  3.3*1.2*1.5=5.94
   Box Box2(8.5, 6.0, 2.0);    // Declare box2   8.5*6*2=102
 
   if(Box1.compare(Box2))
   {
      cout << "Box2 is smaller than Box1" <<endl;
   }
   else
   {
      cout << "Box2 is equal to or larger than Box1" <<endl;
   }
   return 0;
}

Operation results:
Constructor called.
Constructor called.
Box2 is equal to or larger than Box1

8. Pointer to class in C + +

A pointer to a C + + class is similar to a pointer to a structure. To access a member of a pointer to a class, you need to use the member access operator - >, just like accessing a pointer to a structure. Like all pointers, you must initialize the pointer before using it.

The following examples help to better understand the concept of pointers to classes:

#include <iostream>
 
using namespace std;

class Box
{
   public:
      // Constructor definition
      Box(double l=2.0, double b=2.0, double h=2.0)
      {
         cout <<"Constructor called." << endl;
         length = l;
         breadth = b;
         height = h;
      }
      double Volume()
      {
         return length * breadth * height;
      }
   private:
      double length;     // Length of a box
      double breadth;    // Breadth of a box
      double height;     // Height of a box
};

int main(void)
{
   Box Box1(3.3, 1.2, 1.5);    // Declare box1
   Box Box2(8.5, 6.0, 2.0);    // Declare box2
   Box *ptrBox;                // Declare pointer to a class.

   // Save the address of the first object
   ptrBox = &Box1;

   // Now try using the member access operator to access members
   cout << "Volume of Box1: " << ptrBox->Volume() << endl;

   // Save the address of the second object
   ptrBox = &Box2;

   // Now try using the member access operator to access members
   cout << "Volume of Box2: " << ptrBox->Volume() << endl;
  
   return 0;
}

Operation results:
Constructor called.
Constructor called.
Volume of Box1: 5.94
Volume of Box2: 102

9. Static members of C + + classes

We can use the static keyword to define class members as static. When we declare that the members of a class are static, this means that no matter how many class objects are created, there is only one copy of the static members.
Static members are shared among all objects of the class. If there are no other initialization statements, all static data will be initialized to zero when the first object is created. We cannot place the initialization of static members in the definition of a class, but we can initialize a static variable by redefining it outside the class by using the range resolution operator:: as shown in the following example.

The following examples help to better understand the concept of static member data:

#include <iostream>
 
using namespace std;
 
class Box
{
   public:
      static int objectCount;
      // Constructor definition
      Box(double l=2.0, double b=2.0, double h=2.0)
      {
         cout <<"Constructor called." << endl;
         length = l;
         breadth = b;
         height = h;
         // Increase by 1 each time you create an object
         objectCount++;
      }
      double Volume()
      {
         return length * breadth * height;
      }
   private:
      double length;     // length
      double breadth;    // width
      double height;     // height
};
 
// Initialize static members of class Box
int Box::objectCount = 0;
 
int main(void)
{
   Box Box1(3.3, 1.2, 1.5);    // Declaration box1
   Box Box2(8.5, 6.0, 2.0);    // Declaration box2
 
   // Total number of output objects
   cout << "Total objects: " << Box::objectCount << endl;
 
   return 0;
}

Operation results:
Constructor called.
Constructor called.
Total objects: 2

Static member function

If you declare a function member static, you can separate the function from any specific object of the class. Static member functions can be called even when the class object does not exist. Static functions can be accessed as long as they use the class name plus range resolution operator::.

Static member functions can only access static member data, other static member functions, and other functions outside the class.

Static member functions have a class scope, and they cannot access the class's this pointer. You can use static member functions to determine whether some objects of a class have been created.

Differences between static member functions and ordinary member functions:

  • Static member functions have no this pointer and can only access static members (including static member variables and static member functions).
  • Ordinary member functions have this pointer, which can access any member in the class; Static member functions have no this pointer.
#include <iostream>
 
using namespace std;
 
class Box
{
   public:
      static int objectCount;
      // Constructor definition
      Box(double l=2.0, double b=2.0, double h=2.0)
      {
         cout <<"Constructor called." << endl;
         length = l;
         breadth = b;
         height = h;
         // Increase by 1 each time you create an object
         objectCount++;
      }
      double Volume()
      {
         return length * breadth * height;
      }
      static int getCount()
      {
         return objectCount;
      }
   private:
      double length;     // length
      double breadth;    // width
      double height;     // height
};
 
// Initialize static members of class Box
int Box::objectCount = 0;
 
int main(void)
{
  
   // The total number of output objects before they were created
   cout << "Inital Stage Count: " << Box::getCount() << endl;
 
   Box Box1(3.3, 1.2, 1.5);    // Declaration box1
   Box Box2(8.5, 6.0, 2.0);    // Declaration box2
 
   // Total number of output objects after object creation
   cout << "Final Stage Count: " << Box::getCount() << endl;
 
   return 0;
}

Operation results:
Inital Stage Count: 0
Constructor called.
Constructor called.
Final Stage Count: 2

Topics: C++