[C++] Classes and Objects (Part 2)

Default member function of a class

If a class has no members, it is referred to as an empty class. Nothing in the empty class? No, any class will automatically generate the following 6 default member functions if we don't write it.
insert image description here

Constructor

The constructor is a special member function with the same name as the class name . It is automatically called by the compiler when an object of a class type is created, ensuring that each data member has an appropriate initial value and is called only once during the object's life cycle.

The main task of the constructor is not to create an object, but to initialize the object.

feature:

  1. The function name is the same as the class name.
  2. No return value.
  3. The compiler automatically calls the corresponding constructor when the object is instantiated.
  4. Constructors can be overloaded.

Code example:

class Date
{
    
    
public :
	// 1.无参构造函数
	Date ()
	{
    
    }
	// 2.带参构造函数
	Date (int year, int month , int day )
	{
    
    
		_year = year ;
		_month = month ;
		_day = day ;
	}
private :
	int _year ;
	int _month ;
	int _day ;
};
void TestDate()
{
    
    
	Date d1; // 调用无参构造函数
	Date d2 (2015, 1, 1); // 调用带参的构造函数
	// 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明
	// 以下代码的函数:声明了d3函数,该函数无参,返回一个日期类型的对象
	Date d3();
}

If there is no explicitly defined constructor in the class, the C++ compiler will automatically generate a no-argument default constructor, and once the user explicitly defines it, the compiler will no longer generate it.

Code example:

class Date
{
    
    
public:
	/*
	// 如果用户显式定义了构造函数,编译器将不再生成
	Date (int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	*/
private:
	int _year;
	int _month;
	int _day;
};

void Test()
{
    
    
	// 没有定义构造函数,对象也可以创建成功,因此此处调用的是编译器生成的默认构造函数
	Date d;
}

Both the parameterless constructor and the all-default constructor are called default constructors, and there can only be one default constructor.
Note: No-argument constructors, full default constructors, and constructors generated by default by the compiler can all be considered as default member functions.

Code example:

// 默认构造函数
class Date
{
    
    
public:
	Date()
	{
    
    
		_year = 1900 ;
		_month = 1 ;
		_day = 1;
	}
	Date (int year = 1900, int month = 1, int day = 1)
	{
    
    
		_year = year;
		_month = month;
		_day = day;
	}
private :
	int _year ;
	int _month ;
	int _day ;
};
// 以下测试函数能通过编译吗?
void Test()
{
    
    
	Date d1;
}

C++ divides types into built-in types (primitive types) and custom types. The built-in type is the type that has been defined by the grammar: such as int/char..., the custom type is the type that we define by using class/struct/union. If you look at the following program, you will find that the compiler generates a default constructor that will Its default member function called by the custom type member _t.

class Time
{
    
    
public:
	Time()
	{
    
    
		cout << "Time()" << endl;
		_hour = 0;
		_minute = 0;
		_second = 0;
	}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
    
    
private:
	// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;
	// 自定义类型
	Time _t;
};
int main()
{
    
    
	Date d;
	return 0;
}

destructor

Destructor: Contrary to the function of the constructor, the destructor does not complete the destruction of the object, and the local object destruction is done by the compiler. When the object is destroyed, the destructor will be automatically called to complete some resource cleanup work of the class.

feature:

  1. The destructor name is preceded by the character ~ before the class name.
  2. No parameters, no return value.
  3. A class has one and only one destructor. If not explicitly defined, the system will automatically generate a default destructor.
  4. When the object life cycle ends, the C++ compilation system automatically calls the destructor.

Code example:

typedef int DataType;
class SeqList
{
    
    
public :
	SeqList (int capacity = 10)
	{
    
    
		_pData = (DataType*)malloc(capacity * sizeof(DataType));
		assert(_pData);
		_size = 0;
		_capacity = capacity;
	}
	~SeqList()
	{
    
    
		if (_pData)
		{
    
    
			free(_pData ); // 释放堆上的空间
			_pData = NULL; // 将指针置为空
			_capacity = 0;
			_size = 0;
		}
	}
private :
	int* _pData ;
	size_t _size;
	size_t _capacity;
};

Compiler-generated default destructor that calls its destructor for members of a custom type.

Code example:

class String
{
    
    
public:
	String(const char* str = "jack")
	{
    
    
		_str = (char*)malloc(strlen(str) + 1);
		strcpy(_str, str);
	}
	~String()
	{
    
    
		cout << "~String()" << endl;
		free(_str);
	}
private:
	char* _str;
};

class Person
{
    
    
private:
	String _name;
	int _age;
};

int main()
{
    
    
	Person p;
	return 0;
}

copy constructor

Constructor: There is only a single formal parameter, which is a reference to an object of this class type (usually const modified), which is automatically called by the compiler when a new object is created with an existing class type object.

feature:

  1. The copy constructor is an overloaded form of the constructor.
  2. The copy constructor has only one parameter and must be passed by reference. Using the pass-by-value method will cause infinite recursive calls.
  3. If no definition is displayed, the system generates a default copy constructor. The default copy constructor object is copied in byte order according to the memory storage. This copy is called shallow copy, or value copy.

assignment operator overloading

By default, operators are used for built-in type variables. If a variable of a user-defined type wants to use these operators, you must overload the operators yourself.
Operator overloading means that we have to write a function definition to implement the behavior of this operator.

C++ introduces operator overloading to enhance the readability of the code. Operator overloading is a function with a special function name, as well as its return value type, function name and parameter list. Its return value type and parameter list are similar to ordinary functions.

The function name is: the keyword operator followed by the operator symbol that needs to be overloaded.
Function prototype: Return value type operator operator (parameter list).

Note:
1. A new operator cannot be created by concatenating other symbols: such as operator@
2. An overloaded operator must have an operand of a class type or an enumeration type
3. The meaning of an operator for a built-in type cannot be Change, for example: the built-in integer +, cannot change its meaning
4. When an overloaded function is a class member, its formal parameters appear to be one less than the number of operands. The operator of the member function has a default parameter this, which is limited to The first formal parameter
5. .* , :: , sizeof , ?: , . Note that the above 5 operators cannot be overloaded.

Assignment operator overloading:

  1. Parameter Type
  2. return value
  3. Check if you assign yourself a value
  4. return *this
  5. If a class does not explicitly define an assignment operator overload, the compiler will also generate one to complete the endian value copy of the object.

const-modified class member function

A const-modified class member function is called a const member function, and a const-modified class member function actually modifies the implicit this pointer of the member function, indicating that no member of the class can be modified in the member function.

insert image description here

  1. Can a const object call a non-const member function? cannot
  2. Can non-const objects call const member functions? can

Take address and const take address operator overloading

These two default member functions generally do not need to be redefined, and the compiler will generate them by default.

class Date
{
    
    
public :
	Date* operator&()
	{
    
    
		return this ;
	}
	const Date* operator&()const
	{
    
    
		return this ;
	}
private :
	int _year ; // 年
	int _month ; // 月
	int _day ; // 日
};

Generally, these two operators do not need to be overloaded. You can use the overload of the default address generated by the compiler. Only in special cases, overloading is required, for example, if you want others to get the specified content!

Guess you like

Origin blog.csdn.net/qq_46994783/article/details/123511132