C++. Structures and inheritance. Structures and polymorphism. Abstract structure. Overloading of operators in structures. Static Methods in Structures

Structures and inheritance. Structures and polymorphism. Abstract structure. Overloading of operators in structures. Static methods in structures

In this topic, examples show the possibilities of structures in modern C++, which are in no way inferior to classes. In most case the need to use structures in modern C ++ is to ensure compatibility with useful programs developed in previous years in the C language. It makes no sense to rewrite these programs from scratch, as this requires significant time and human resources.


Contents


Search other websites:




1. Do structures support inheritance? Example

Yes they do. Structures support inheritance.

The following example demonstrates the use of inherited structures. The basic structure Worker describes the data about the worker: name and age. The derived structure WorkerAge contains methods for accessing the fields of the underlying structure. Also is demonstrated:

  • access from the constructor of the derived structure to the constructor of the base structure;
  • access to the protected field of the base structure from the inherited structure;
  • using the this pointer to access the field of the base structure.

As you can see from the example, in new versions of C++ structures are a simplified version of classes.

 

#include <iostream>
using namespace std;

// Structure describing employee data - basic structure
struct Worker
{
private:
  string name; // internal field, the name of worker

public:
  // Constructor
  Worker(string _name)
  {
    name = _name;
  }

  // Access methods to the field name
  string GetName()
  {
    return name;
  }

  void SetName(string _name)
  {
    name = _name;
  }

protected:
  int age; // protected field - worker's age
};

// Inherited structure from Worker
struct WorkerAge :Worker
{
  // Constructor with 2 parameters, it invokes the constructor of base structure
  WorkerAge(string _name, int _age) :Worker(_name)
  {
    age = _age;
  }

  // Constructor with 1 parameter
  WorkerAge(int age) :Worker("Noname")
  {
    this->age = age; // access via this pointer to given structure
  }

  // Access methods to the field age
  int GetAge()
  {
    return age;
  }

  void SetAge(int _age)
  {
    age = _age;
  }
};

void main()
{
  // Methods in structures

  // 1. Using the Worker structure
  Worker w(""); // declare an structure instance, constructor is used
  w.SetName("John"); // access to the field name

  string nm = w.GetName();
  cout << nm.c_str() << endl;

  // 2. Using the structure WorkerAge
  WorkerAge wa("Micle", 33);
  cout << wa.GetName().c_str() << endl;
  cout << wa.GetAge() << endl;
}

The result of the program

John
Micle
33

 

2. Can a structure be abstract? Do structures support polymorphism?

The structure can be abstract. This means that in modern versions of C++, structures support polymorphism.

 

3. An example that demonstrates the use of polymorphism in structures

Like classes, structs support polymorphism. The example demonstrates the use of polymorphism for structures that implement inheritance.

Four structures are declared with the names A, B, C, D. These structures form an inheritance hierarchy. Structure A is basic for structure B. Structure B is basic for structure C. Structure C is basic for structure D.

Each structure implements a Print() method. Structure A is basic for structures B, C, D. In this structure, the Print() method is declared as a pure virtual function. Such a method does not contain a method body. This means that the structure A is abstract. According to the C++ syntax, it is forbidden to declare an instance of a structure A, you can only declare a pointer or a reference to this structure.

The example also implements the PrintStruct() method, which gets a reference to the underlying structure A and calls the virtual Print() method.

The main() function demonstrates the use of polymorphism in two ways:

  • using a pointer to the base structure;
  • using a reference to the base structure in the PrintStruct() method.

 

#include <iostream>
using namespace std;

// A structure that contains a pure virtual function - an abstract structure
struct A
{
  virtual void Print() = 0;
};

// Inherited structures B, C, D
struct B :A
{
  void Print() override
  {
    cout << "B.Print()" << endl;
  }
};

struct C :B
{
  void Print() override
  {
    cout << "C.Print()" << endl;
  }
};

struct D :C
{
  void Print() override
  {
    cout << "D.Print()" << endl;
  }
};

// Method that gets a reference to the base structure,
// this method invokes the Print() method of this structure
void PrintStruct(A& refA)
{
  refA.Print(); // invoke method Print()
}

void main()
{
  // Demonstration of polymorphism support in structures
  // 1. Declare an internal variables
  A* pA;  // pointer to the base struct A
  B objB; // instance of structure B
  C objC; // instance of structure C
  D objD; // instance of structure D

  // 1. Calling the Print () method in a uniform way (interface)
  //   using a pointer, that points to the different instances of structures
  pA = &objB;  // redirect pointer to an instance of structure B
  pA->Print(); // invoke B.Print()

  pA = &objC;
  pA->Print(); // invoke C.Print()

  pA = &objD;
  pA->Print(); // invoke D.Print()

  // 2. Passing a reference to structure A to the PrintStruct() method
  cout << "-----------------------------------------------------" << endl;

  pA = &objB;
  PrintStruct(*pA);  // invoke B.Print()

  PrintStruct(objB); // invoke B.Print()
  PrintStruct(objC); // invoke C.Print()
  PrintStruct(objD); // invoke D.Print()
}

The result of the program

B.Print()
C.Print()
D.Print()
-----------------------------------------------------
B.Print()
B.Print()
C.Print()
D.Print()

 

4. Overloading operators in a structure. Structure Point. Example

In structures, as in classes, you can use operator functions that overload operators. The following is an example of a Point structure that overloads the + (addition) and (subtraction) operators.

The Point structure declares the following components:

  • public variables x, y that define the coordinates of a point on the plane;
  • two constructors that initialize internal variables;
  • operator function operator+(), which overloads operator + (addition);
  • operator function operator–(), which overloads operator (subtraction);
  • the Print() method for displaying information about the point.

The main() function demonstrates the use of the Point structure.

#include <iostream>
using namespace std;

// Structure describing a point on a coordinate plane
struct Point
{
public:
  double x, y; // coordinates of a point

  // Constructors
  Point()
  {
    x = y = 0;
  }

  Point(double _x, double _y) : x(_x), y(_y)
  { }

  // Overloaded operator +
  Point operator+(Point& pt)
  {
    return Point(x + pt.x, y + pt.y);
  }

  // Overloaded operator -
  Point operator-(Point& pt)
  {
    return Point(x - pt.x, y - pt.y);
  }

  // Overloaded assignment operator
  Point operator=(Point pt)
  {
    x = pt.x;
    y = pt.y;
    return *this;
  }

  // The method of displaying information about a point
  void Print(string objName)
  {
    cout << objName << ": x = " << x << ", y = " << y << endl;
  }
};

void main()
{
  // Demonstration of using the Point structure
  Point pt1(2, 8.5);
  Point pt2(-5.1, 7.5);

  // Initialization - test
  Point pt3 = pt1;
  pt3.Print("pt3");

  // The test of operator function operator+()
  Point pt4 = pt1 + pt2;
  pt4.Print("pt4");

  // Test of operator function operator=()
  Point pt5;
  pt5 = pt3;
  pt5.Print("pt5");

  // Test of combination of operator functions operator-(), operator+()
  Point pt6(1, 1);
  Point pt7(-3, -3);
  cout << "---------------" << endl;
  pt6.Print("pt6");
  pt7.Print("pt7");

  Point pt8 = pt6 - pt7 - pt3 + pt4; // pt8 = (-1.1, 11.5)
  pt8.Print("pt8");
}

 

5. Using static methods and variables in structures. Example

Structures can use static methods and variables. The example implements the Complex structure, which contains static methods for calculating the sum, difference, product and division of complex numbers. Also, the structure implements the Print() method, which displays a complex number in a convenient form. The main() function demonstrates the use of the static methods of the Complex class.

The text of demonstration program of ConsoleApplication type is as follows:

#include <iostream>
using namespace std;

// The text of demonstration program of ConsoleApplication type is as follows:
struct Complex
{
  // Public static methods
  // Addition of complex numbers (a1+b1*i) + (a2+b2*i)
  static void Add(double a1, double b1, double a2, double b2,
                  double& a, double& b)
  {
    a = a1 + a2;
    b = b1 + b2;
  }

  // Substraction of complex numbers
  static void Sub(double a1, double b1, double a2, double b2,
                  double& a, double& b)
  {
    a = a1 - a2;
    b = b1 - b2;
  }

  // Multiplication of complex numbers
  static void Mul(double a1, double b1, double a2, double b2,
                  double& a, double& b)
  {
    a = a1 * a2 - b1 * b2;
    b = a1 * b2 + b1 * a2;
  }

  // Division of complex numbers
  static void Div(double a1, double b1, double a2, double b2,
                  double& a, double& b)
  {
    double denom = a2 * a2 + b2 * b2;

    // Checking if two numbers can be divide correctly
    if (denom == 0)
    {
      a = b = 0; // set zero values
      return;
    }

    a = (a1 * a2 + b1 * b2) / denom;
    b = (a2 * b1 - a1 * b2) / denom;
  }

  // Displays information about the complex number
  static void Print(string text, double a, double b)
  {
    // Set precision to 2 decimal places
    cout.precision(2);

    cout << text << a;
    if (b > 0)
      cout << "+";
    cout << b << "*i" << endl;
  }
};

void main()
{
  // Static methods in a structure
  double a1 = 3, b1 = 2.5;
  double a2 = 7, b2 = -1.8;
  double a, b;

  // Display the first number
  Complex::Print("z1 = ", a1, b1);

  // Display the second number
  Complex::Print("z2 = ", a2, b2);

  // Calculate the sum, result in a, b
  Complex::Add(a1, b1, a2, b2, a, b);
  Complex::Print("z1 + z2 = ", a, b);

  // Calculate substraction
  Complex::Sub(a1, b1, a2, b2, a, b);
  Complex::Print("z1 - z2 = ", a, b);

  // Calculate multiplication
  Complex::Mul(a1, b1, a2, b2, a, b);
  Complex::Print("z1 * z2 = ", a, b);

  // Calculate division
  Complex::Div(a1, b1, a2, b2, a, b);
  Complex::Print("z1 / z2 = ", a, b);
}

The result of the program:

z1 = 3+2.5*i
z2 = 7-1.8*i
z1 + z2 = 10+0.7*i
z1 - z2 = -4+4.3*i
z1 * z2 = 26+12*i
z1 / z2 = 0.32+0.44*i

 


Related topics