Catalog
1. Destructive function
- In C++ classes, you can define a special cleanup function called destructor. The grammatical rule is ~ClassName().
- Destructors have no parameters and no return value type declaration
- Destructors are called automatically when objects are destroyed
- When a constructor is defined in a class and system resources are used in the constructor (e.g. heap space, file opening, etc.), a custom destructor is required.
2. Object construction and destructive order
Between multiple objects
When multiple objects are constructed:
- The construction order of stack objects depends on the execution flow of the program.
- The construction order of heap objects depends on the usage order of new
- The construction order of global objects is uncertain, and different compilers may use different rules.
When multiple objects are destructed:
- The deconstruction order of stack objects and global objects is contrary to the construction order.
- Deconstruction of heap objects depends on the order in which delete s are used
Inside a single object
When a single object is created, the order of invocation of the constructor inside the object is:
- Call the constructor of the parent class first
- Call the constructor of the member variable in the same order as the declaration
- Finally, call the constructor of the class itself
The order of destructions within a single object is contrary to that of constructions.
3. const object and const member function
const object
- Objects modified by const keywords are read-only objects
- Membership variables of read-only objects are not allowed to be changed
- Read-only properties are valid only at compilation stage and not at runtime
const member function
The definitions of const member functions are as follows. It is important to note that both function declarations and function definitions must have const keywords.
Type ClassName :: func(Type para) const
For the use of const member functions, there are the following rules:
- Const objects can only call const member functions
- Const member function can only call const member function
- const member functions cannot directly modify the values of member variables
#include <stdio.h> class Test { int mi; public: Test(int i); void setMi(int i) const; int getMi() const; void printMi(); }; Test::Test(int i) { mi = i; } void Test::setMi(int i) const { mi = i; //Error, const member function can not directly modify the value of member variables } int Test::getMi() const { return mi; } void Test::printMi() { printf("printMi(): mi = %d\n", mi); } int main() { const Test t1(1); t1.getMi(); //OK, const object calls const member function t1.printMi(); //Error, const object calls ordinary member functions return 0; }
4. Relations among member functions, member variables and objects
From the object-oriented point of view, objects are composed of attributes (member variables) and methods (member functions).
From the point of view of program operation, objects are composed of data and functions. Data is located in stack, heap or global data area, and functions are located in code segment.
- Each object has its own independent attributes (member variables)
- All Object Sharing Class Method (Member Function)
- Method can directly access the properties of an object
- The hidden parameter this pointer in the method is used to replace the current object
#include <stdio.h> class Test { int mi; public: int mj; Test(int i); Test(const Test &t); int getMi(); void print(); }; Test::Test(int i) { mi = i; } Test::Test(const Test &t) { mi = t.mi; //Membership functions can directly access member variables of corresponding class objects } int Test::getMi() { return mi; } void Test::print() { printf("this = %p\n", this); //A this pointer is hidden in each member function to point to the current object } int main() { Test t1(1); Test t2(2); Test t3(3); printf("t1.getMi() = %d\n", t1.getMi()); printf("&t1 = %p\n", &t1); t1.print(); printf("t2.getMi() = %d\n", t2.getMi()); printf("&t2 = %p\n", &t2); t2.print(); printf("t3.getMi() = %d\n", t3.getMi()); printf("&t3 = %p\n", &t3); t3.print(); return 0; }
5. Code Actual Warfare - Array Class IntArray
IntArray.h
#ifndef _INTARRAY_H_ #define _INTARRAY_H_ class IntArray { private: int m_length; int *m_pointer; public: IntArray(int len); IntArray(const IntArray &obj); int length(); bool get(int index, int &value); bool set(int index ,int value); ~IntArray(); }; #endif
IntArray.cpp
#include "IntArray.h" IntArray::IntArray(int len) { m_pointer = new int[len]; for(int i=0; i<len; i++) { m_pointer[i] = 0; } m_length = len; } IntArray::IntArray(const IntArray &obj) { m_length = obj.m_length; m_pointer = new int[obj.m_length]; for(int i = 0; i < obj.m_length; i++) { m_pointer[i] = obj.m_pointer[i]; } } int IntArray::length() { return m_length; } bool IntArray::get(int index, int &value) { bool ret = (0 <= index) && (index < length()); if( ret ) { value = m_pointer[index]; } return ret; } bool IntArray::set(int index, int value) { bool ret = (0 <= index) && (index < length()); if( ret ) { m_pointer[index] = value; } return ret; } IntArray::~IntArray() { delete[] m_pointer; }
IntArray test
#include "IntArray.h" #include <stdio.h> int main() { IntArray a(5); for(int i = 0; i < a.length(); i++) { a.set(i, i + 1); } for(int i = 0; i < a.length(); i++) { int value = 0; if( a.get(i, value) ) { printf("a[%d] = %d\n", i, value); } } IntArray b = a; for(int i = 0; i < b.length(); i++) { int value = 0; if( b.get(i, value) ) { printf("b[%d] = %d\n", i, value); } } return 0; }