C++. Structures. Using methods in structures. Constructors in structures

Structures. Using methods in structures. Constructors in structures


Contents


Search other websites:




1. Features of using methods in structures

Methods can be used in structures. Using methods in structures is no different than using methods in classes. As well as in classes, constructors can be implemented in structures.

If a method is declared in the structure without an access modifier (private, protected, public), then this method is considered public by default.

 

2. How is the size of the structure that contains the methods determined? Example

If methods are declared in the structure, then they do not affect the size of the structure variable, which is determined by the sizeof operator. The size of a structured variable is determined only based on the internal data described in the structure.

Example. The example declares a Book structure without methods. The main() function displays the size of the structure as determined by the sizeof operator.

#include <iostream>
using namespace std;

// Structure Book, implements a book
struct Book
{
  char title[100]; // title of book
  char author[100]; // author's name
  int year; // the year of publishing
  double price; // cost
};

void main()
{
  // Determine the size of the Book structure
  Book b;
  int size = sizeof(b); // size = 216
  cout << "size = " << size << endl;
}

If you try to add a method to the structure, for example, like this

struct Book
{
  char title[100]; // title of book
  char author[100]; // author's name
  int year; // year of publishing
  double price; // cost

  void Print()
  {
    cout << "title = " << title << endl;
    cout << "author = " << author << endl;
    cout << "year = " << year << endl;
    cout << "price = " << price << endl;
  }
};

then the size of the structure will not change. After running for execution, in both cases the program will give the same result

size = 216

 

3. An example of using methods in structures. SquareEquition structure – solving a quadratic equation

Implemented the SquareEquition structure, which contains all the necessary tools for solving a quadratic equation.

Structure SquareEquition:

  • stores the value of the internal variables a, b, c;
  • includes access methods to a, b, c;
  • displays information about solving a quadratic equation in a convenient form.

The structure implements:

  • hidden (private) internal fields a, b, c, which are the coefficients of the equation;
  • constructor with three parameters corresponding to the coefficients of the equation;
  • public method Solve(), which finds a solution of a quadratic equation;
  • public method PrintSolve(), which displays the solution of a quadratic equation on the screen;
  • the GetABC() and SetABC() methods for accessing the internal fields a, b, c.

 

#include <iostream>
using namespace std;

// Structure that implements a quadratic equition
struct SquareEquition
{
private:
  // internal fields of structure
  double a, b, c;

public:
  // Constructor
  SquareEquition(double a, double b, double c)
  {
    this->a = a;
    this->b = b;
    this->c = c;
  }

  // Access methods
  void GetABC(double& a, double& b, double& c)
  {
    a = this->a;
    b = this->b;
    c = this->c;
  }

  void SetABC(double a, double b, double c)
  {
    this->a = a;
    this->b = b;
    this->c = c;
  }

  // Method Solve(),
  // returns true if the equation has a solution.
  bool Solve(double& x1, double& x2)
  {
    // Checking if an equation is a quadratic equation
    if (a == 0) return false;

    // calculate the discriminant
    double d = b * b - 4 * a*c;

    // checking if the equation has roots
    if (d < 0)
    {
      x1 = x2 = 0;
      return false;
    }

    // calculation of roots
    x1 = (-b - sqrt(d)) / (2 * a);
    x2 = (-b + sqrt(d)) / (2 * a);

    return true;
  }

  // Method, displays the solution of a quadratic equation,
  // this method calls Solve() to get the roots of the equation.
  void PrintSolve()
  {
    double x1, x2;

    cout << "The equation: ";

    if (a != 0)
      cout << a << "*a";

    if (b != 0)
    {
      if (b > 0)
        cout << "+";
      cout << b << "*b";
    }

    if (c != 0)
    {
      if (c > 0)
        cout << "+";
      cout << c << "*c";
    }

    cout << " = 0" << endl;

    if (Solve(x1, x2)) // is there a solution?
    {
      cout << "has the following roots: " << endl;
      cout << "x1 = " << x1 << endl;
      cout << "x2 = " << x2 << endl;
    }
    else
    {
      cout << "has no roots. ";
    }
  }
};

void main()
{
  // Structure SquareEquition
  SquareEquition e(-3, 1, 5.5); // invoke the constructor
  e.PrintSolve(); // invoke method PrintSolve() of the structure
}

After launch, the program produced the following result

The equation: -3*a+1*b+5.5*c = 0
has the following roots:
x1 = 1.53089
x2 = -1.19756

 

4. Constructors and destructors in structures. Features of use

Structures, like classes, can contain constructors. The following rules for using constructors are established for structures:

  • the structure can have any number of constructors that differ in the types of parameters and / or the number of parameters;
  • the structure can contain constructors that are declared in the access sections: private, public, protected;
  • if there is no constructor in the structure, then a variable (instance) of the structure type is created in the usual way without specifying parameters;
  • if a public constructor is declared in a structure, then an instance of the structure must be created with parameters that correspond to this constructor.

Destructors can also be used in the structure. As a rule, destructors perform operations to free the used resources, memory, close the files in use, etc.

 

5. An example of using constructors and a destructor in a structure. Structures Point, ArrayPoint

The example demonstrates the use of constructors and destructors in structures.
Two structures are declared:

  • a Point structure that implements a point on the coordinate plane;
  • an ArrayPoint structure – implements an array of points of type Point.

A Point structure contains the following components:

  • public internal variables x, y;
  • constructor Point() without a parameters, which initializes internal variables to zero values;
  • constructor with 2 parameters Point(double, double) – initializes internal fields.

Structure of ArrayPoint type declares the following elements:

  • hidden (private) field A – an array of elements of type Point;
  • hidden field count – number of elements in array A;
  • constructor ArrayPoint() without parameters;
  • constructor ArrayPoint(Point*, int) with parameter of another array. This consturctor initializes array A with elements of another array Point[];
  • copy constructor ArrayPoint(const ArrayPoint&). Since pointers are used in the ArrayPoint structure, this constructor is necessary for the correct initialization of instances of structures of the ArrayPoint type and also for the correct return from the function of an instance of the ArrayPoint type;
  • methods for accessing array elements GetP(int) and SetP(Point, int);
  • destructor ~ArrayPoint(). The memory allocated for an array of type Point* is released in the destructor;
  • the mehtod Copy(const ArrayPoint &), copies one array of ArrayPoint type to another array;
  • method Print() – displays the elements of the ArrayPoint on the screen.

The main() function demonstrates the use of the methods of the ArrayPoint structure.

C++ program for the Console Application template.

#include <iostream>
using namespace std;

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

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

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

// Dynamic array of points of type Point
struct ArrayPoint
{
private:
  Point* A; // pointer to array
  int count; // number of items in the array

public:
  // Overloaded constructor Array()
  // Constructor without parameters
  ArrayPoint()
  {
    count = 0;
    A = nullptr;
  }

  // Constructor with parameter of another array
  ArrayPoint(Point* _A, int _count)
  {
    // Initialize array A with another array
    count = _count;
    A = new Point[count]; // allocate memory

    for (int i = 0; i < count; i++)
    {
      A[i].x = _A[i].x;
      A[i].y = _A[i].y;
    }
  }

  // Copy constructor.
  // Needed because memory in the structure is dynamically allocated
  ArrayPoint(const ArrayPoint& _A)
  {
    count = _A.count;

    // allocate memory for array A
    A = new Point[count];

    // elementwise copying
    for (int i = 0; i < count; i++)
    {
      A[i].x = _A.A[i].x;
      A[i].y = _A.A[i].y;
    }
  }

  // Access methods to array items
  Point GetP(int index)
  {
    // Checking if the index is within acceptable limits
    if ((index >= 0) && (index < count))
    {
      return A[index];
    }

    // if the index is out of bounds, then return point (0, 0)
    return Point();
  }

  void SetP(Point pt, int index)
  {
    // Checking if the index is within acceptable limits
    if ((index >= 0) && (index < count))
    {
      A[index].x = pt.x;
      A[index].y = pt.y;
    }
  }

  // Destructor
  ~ArrayPoint()
  {
    // release memory, allocated for array A
    if (count > 0)
      delete[] A;
  }

  // Method of copying one array to another
  void Copy(const ArrayPoint& _A)
  {
    // Release pre-allocated memory
    if (count > 0)
      delete[] A;

    // Allocate memory in a new way
    count = _A.count;
    A = new Point[count];

    // element-wise assignment
    for (int i = 0; i < count; i++)
    {
      A[i].x = _A.A[i].x;
      A[i].y = _A.A[i].y;
    }
  }

  // A method that displays array A
  void Print()
  {
    cout << "A: " << endl;
    for (int i = 0; i < count; i++)
    {
      cout << "(" << A[i].x << ", " << A[i].y << ")";

      if (i != count - 1)
        cout << ", ";
    }
    cout << endl;
  }
};

void main()
{
  // Using constructors and destructors in the structure

  // Declare two arrays of points and other internal data structures
  Point P1[3] = {
    Point(1.5, 2.8),
    Point(-1.3, 0.8),
    Point(-2.2, 5.5)
  };

  Point P2[2] = {
    Point(0.5,3.8),
    Point(2.9,1.6)
  };

  // Create instances of arrays ArrayPoint
  ArrayPoint AP1(P1, 3);
  ArrayPoint AP2(P2, 2);

  // Display arrays AP1, AP2
  cout << "AP1.";
  AP1.Print();

  cout << "---------------" << endl;
  cout << "AP2.";
  AP2.Print();

  // Check copy constructor, declare third ArrayPoint
  ArrayPoint AP3 = AP1;
  cout << "----------------" << endl;
  cout << "AP3.";
  AP3.Print();

  // Check method Copy(), copying AP2=>AP3
  AP3.Copy(AP2);
  cout << "----------------" << endl;
  cout << "AP3.Copy(AP2) => AP3=AP2" << endl;
  cout << "AP2.";
  AP2.Print();
  cout << "AP3.";
  AP3.Print();

  // Check method GetP()
  Point pt1 = AP1.GetP(1);
  cout << "--------------" << endl;
  cout << "AP1[1] = (" << pt1.x << ", " << pt1.y << ")" << endl;
}

The result of the program

AP1.A:
(1.5, 2.8), (-1.3, 0.8), (-2.2, 5.5)
---------------
AP2.A:
(0.5, 3.8), (2.9, 1.6)
----------------
AP3.A:
(1.5, 2.8), (-1.3, 0.8), (-2.2, 5.5)
----------------
AP3.Copy(AP2) => AP3=AP2
AP2.A:
(0.5, 3.8), (2.9, 1.6)
AP3.A:
(0.5, 3.8), (2.9, 1.6)
--------------
AP1[1] = (-1.3, 0.8)

 


Related topics