[C + +] object oriented -- class and object

Posted by Joel.DNSVault on Sat, 19 Feb 2022 17:35:19 +0100

***

Class definitions and class members

Define a class:

class Box
{
   private:
      double length;   // Length of a box
      double breadth;  // Breadth of a box
      double height;   // Height of a box
   public:
   	  double getArea();
};

The defined class has the following properties: class name, class members (including data and functions), and access properties of members.

After a class is defined, it can not be used directly. You need to instantiate it before you can use these defined class members.

Instantiate a class:

Box box_a;

There are two ways to initialize class data members:

  1. Initialize the class when it is declared (after C++11)
class Box
{
   private:
      double length{1};   // Length of a box
      double breadth{2};  // Breadth of a box
      double height{3};   // Height of a box
};
  1. Initialize in constructor (constructor & destructor)

Access properties:
The access attributes of class members are specified through the internal tags public, private and protected of each region in the class body. These three keywords are called access specifiers. If not specified, it defaults to private member.

  1. public member:
    Class can be accessed externally, and the value of public variables can be obtained and set directly.

  2. private member:
    It can only be accessed through members inside the class. Some interfaces (class public function or friend function) need to be provided to obtain and set the value of private variables.

  3. protected members:
    Class is not accessible outside, but derived classes that inherit this class can access.

Access class members:
use. Operator to access class members.

box.height = 1;	//Access data and assign values. If the member is private, the compiler will report an error
box.getArea();	//Accessing class member functions

Constructor & destructor

Constructors and destructors are called when creating and destroying class instance objects respectively. These functions are defined to achieve specific effects.

1. Constructor
The function name of the constructor is the same as the class name. It will not return any type. It is generally used for the initialization of class objects.

class Box
{
	private:
		double length;
		double breadth;
     	double height;
   	public:
   		Box(double a, double b, double c);	//Declaration constructor
};
//Define constructor
Box::Box(double a=1.0, double b=2.0, double c=3.0)
{
	length = a;
	breadth = b;
	height = c;
}

Constructor can take parameters or not. For constructors with parameters, you need to fill in arguments or use default parameters when instantiating objects.

Box box_a(1, 2, 3);

These fields can also be initialized using the initialization list.

Box::Box(int a, int b, int c): length(a), breadth(b), height(c)
{
}

This writing method has the same function as the above definition.

Q: Why define constructors outside of class definitions?

The function defined in the class definition is considered as an inline function. When this kind of function is called, the compiler will directly copy its function body copy and replace the called statement. That is to shorten the running time at the cost of expanding storage space.
For some short functions, the execution efficiency can be improved; However, for constructors and some complex functions, the efficiency is not improved, and the risk of direct replacement is high, so it is not recommended.

An inline function is defined in the program, and the keyword inline can be used.

inline int add(int a, int b)
{
	return a + b;
}
  1. Destructor
    The function name of the destructor is one more than the class name. It cannot take any parameters and will not return any types. It is generally used to release resources before jumping out of the program.
class Box
{
	private:
		double length;
		double breadth;
     	double height;
   	public:
   		~Box();	//Declare destructor
};
//Define constructor
Box::Box()
{
	cout << "everything is ready." << endl;
}

copy constructor

The function name of the copy constructor is the same as the class name (i.e. the same as the function name of the constructor), which is called in the following cases:

  1. Initialize another object of the same kind with an instantiated object.
Box box_a(1, 2, 3);
Box box_b = box_a;	//Instead of direct assignment, the copy constructor will be called
  1. Pass an object as an argument into a function
  2. Returns an object from a function

The common writing of copy constructor is as follows:

class Box
{
	private:
		double length;
		double breadth;
     	double height;
   	public:
   		Box(const Box &obj);	//Declare copy constructor
};
Box::Box(const Box &obj)
{
	length = obj.length;
	breadth = obj.breadth;
	height = obj.bread;
}

Copy constructors enrich the methods of creating objects. If you don't define a copy constructor for a class, the compiler will also define one for you.

Q: Why should const and reference (&) be used for formal parameters when defining copy constructors?

Different from the assignment of variables, referencing a variable will not create a new memory space for it, which is equivalent to marking a new label on the original memory. The memory can be accessed through this new label. After the reference is defined, the memory space pointed to cannot be replaced, but the content of the memory space can be changed.
In the copy constructor, reference an object to assign a value to the new object, instead of creating a temporary copy of the object and assigning it to the new object. Because the copy constructor will also be called when creating a copy, it falls into a recursive loop of constantly creating copies.
Use the const keyword to prevent modifications to the contents of the memory space pointed to by the reference inside the copy constructor.

Q: Why does the copy constructor have the same name as the constructor function without error or overload coverage?

In C + +, multiple meanings of function names in the same scope are allowed, which is called function overloading. Overload a function with an overload declaration (declaration with the same function name), but their parameter list cannot be the same. When calling an overloaded function, the compiler will judge the function definition used by the overloaded decision mechanism (comparing the argument type with the formal parameter type). The constructor and copy constructor satisfy the condition of function overloading, which explains this problem.

friend function

Friend functions are defined outside a class, but can access private and protected members of the class. Friend function does not belong to class member. Use the keyword friend to declare a friend function in the class definition.

class Box
{
   double width{1};
   double breadth{2};
   double length{3};
public:
   friend void printArea(Box box);
};
void printArea(Box box)
{
	cout << box.width * box.breadth * box.length << endl;
}

You can also define a friend class of a class, so that all member functions in the friend class can access the private and protected members of the class.

Declaration of friend class:

friend class AuxiBox;

Static member

Static members are shared by all objects of the class and can be accessed directly through the class name. Define a static member in the class and use the keyword static.

class Box
{
	double length{1};
	double width{2};
	double height{3};
	public:
	static int num;	//Declare a static member
	Box();
};
Box::Box(double l=2.0, double b=2.0, double h=2.0)
{
   length = l;
   breadth = b;
   height = h;
   // Increase by 1 each time you create an object
   num++;
}
int Box::num = 0;	//Initialize static members

After defining the static members in the above code, each time a class object is created, the counter will be incremented by 1.

Static members can be accessed directly through the class name, and of course, object access can be used.

//Direct access to class static members
cout << Box::num << endl;

After the static member is defined, it needs to be initialized. If it is initialized, it will be automatically initialized to 0 when the first instantiated object is created.

It should be noted that we cannot initialize a variable static member when declaring:

C++regulations const Static class members can be initialized directly, and other non const Static class members of need to be declared outside the class
 Initiation

Similarly, you can access and use static members by defining static member functions. Such functions can also be called when no class object is created.

//Declare and define in class
static getNum()
{
	return num;
}
*******************
//Declared in class, defined outside class
Box::getNum()
{
	return num;
}

Note that static member functions can only access global variables and static data members in the same class, but cannot access other static member functions and other functions outside the class.

To call a static member function, you need to add the class name before the function name:

cout << Box::getNum() << endl;

this pointer

All objects in C + + can access their positions through this pointer, which is also a hidden parameter of all member functions.

class Box
{
   private:
   double length;   // Length of a box
   double breadth;  // Breadth of a box
   double height;   // Height of a box
   public:
   double getArea()
    {
   		return length * breadth * height;
    }
   int compare(Box b)
 	{
   	  	return this->getArea() > b.getArea();
   	}
};

This pointer is a const pointer, that is, after the instance object is created, its pointing address has been determined and can no longer point to other addresses. The scope of this pointer is limited to the object, and only member functions can be used.

Friend functions and friend classes are not member functions, so the this pointer of an object cannot be accessed.

Topics: C++ Back-end