Classes and objects follow (c++)

In the last article, we introduced empty classes, and this article ends with classes and objects.

Introduction:

1. Look at the constructor again

2.static member

3. C++11 member initialization new gameplay

4. Tomomoto

5. Inner classes (understand )

content

1. Look at the constructor again

1. Constructor:

2. Initialize and assign initial values:

3. explicit keyword

Two.static member

1. Concept

2. Features

3. Implement a class and calculate how many class objects are created in the program

4. Can a static member function call a non-static member function?

5. Can a non-static member function call a class's static member function?

3. C++11's member initialization new gameplay.

introduce:

 4. Tomomoto

1. Function

2. Friend function

3. Friend class

5. Inner class (understand)

1. Concept

2. Pay attention

3. Features


1. Look at the constructor again

1. Constructor:

When creating an object, the compiler calls the constructor to give each member variable in the object an appropriate initial value. We have already fully understood the constructor when we were in the middle class of classes and objects, and then we will break the previous one. Chapter on the knowledge of constructors.

Take the date class as an example: (just look at the constructor)

One initial assignment:

Date(int year, int month, int day) {
     _year = year;
     _month = month;
     _day = day;
}

Assign initial values ​​multiple times:

Date(int year, int month, int day) {//对成员变量多次赋初值,并不会发生错误.
     _year = year;
     _month = month;
     _day = day;
     _year = 1;
     _day = 2;
     _month = 3;
}

In the previous chapter, when we explained the constructor, the above code was used to initialize the instantiated object, but in fact this method is not initialization, it should be called initial value assignment, because initialization can only Initialize once, and the constructor body can be assigned multiple times, so what is initialization? What is the difference between initializing and initializing? Let's continue to look at the back.

2. Initialize and assign initial values:

(1) Initialization list:

Begins with a colon, followed by a comma-separated list of data members, each "member variable" followed by an initial value or expression in parentheses, given in the C++ rules to allow us to do real Initialization, in this initialization list, each class member variable can only be assigned once, which is the real initialization.

Taking the Date class as an example, the piece between the function name and the function body is called the initialization list:

Date(int year, int month, int day)
 : _year(year)
 , _month(month)
 , _day(day)
 { }

(2) Four characteristics of the initialization list:

①. Each member variable can only appear once in the initialization list. (It is verified that the above initialization can only be initialized once)

②. The class contains the following members, which must be initialized in the position of the initialization list.

   a. Reference member variables: When we learn about references, we understand that initialization is a feature of references.

    b.const member variable: The value of a member variable of const type cannot be changed after initialization, so it must be initialized.

    c. Custom type members. (The class does not have a default constructor): When instantiating an object member without a default constructor, the compiler cannot automatically call the constructor of the class to initialize it, so we need to initialize the list again Manually call its constructor to complete the initialization of the member object.

③. Try to use the initialization list for initialization, because whether you use the initialization list or not, for member variables of custom types, you must use the initialization list to initialize first.

④. The declaration order of member variables in the class is the initialization order in the initialization list. It has nothing to do with the order in the initialization list.

For example: for the following class, the declaration order of its member variables is: _a, _b, _c, so no matter what order these member variables are in the initialization list, _a is initialized first, then _b, and finally _c.

class A {
public:
	A(int a = 1, int b = 2, int c = 3)
		:_a(a)
		,_c(c)
		,_b(b)
	{}

private:
	int _a;
	int _b;
	int _c;
};

3. explicit keyword

source:

Constructors can not only construct and initialize objects, but also have the role of type conversion for single parameter or full default constructors.

introduce:

Take the Date class as an example: we will find that there is no overloading of the assignment operators for numbers and object types, so why does this code still run successfully? (The default generated assignment operator is the assignment of objects to objects)

class Date {
public:
	Date(int a)//单参构造函数
		:_a(a)
	{}

	void Print() {
		cout << _a << " " << _b << " " << _c << endl;
	}
private:
	int _a;
	int _b;
	int _c;
};

int main() {
	Date d1(1);
	d1 = 4;
	d1.Print();
	return 0;
}

operation result:

reason:

The first step is to create an object of type d1 with an initial value of 1.

The second step is to directly assign 4 to the d1 object. Because of the default assignment operator overloading in the class, it will be converted into:  d1.operator=(4) in the compiler, and then we will look at the compiler How is the automatically generated default assignment operator overload defined:  Date operator=(Date b), now we are corresponding, 4 is the initial value when the temporary object b is created after the actual parameter is passed in ---> Date b =4 , exists in this form, just at this time there is a constructor with only one parameter in the class, the implicit conversion occurs, the conversion is established, and finally the assignment is completed, then the problem comes, we obviously do not have assignments to numbers and objects. Why can this equation be completed? Therefore, in order to prevent such things from happening, the explicit keyword is introduced. As long as this keyword is added in front of the constructor of a single parameter, similar implicit conversions will not occur. occurs. (The same is true for the full default constructor)

Two.static member

1. Concept

A class member declared as static is called a static member of the class, a member variable modified with static is called a static member variable; a member function modified with static is called a static member function, and the static member variable must be outside the class to initialize.

2. Features

1. Static members are shared by all class objects and do not belong to a specific instance.

2. Static member variables must be defined outside the class without the static keyword.

3. Static members can be accessed by class name::static member or object.static member. (Class name::static member is recommended because the object.static member will eventually be converted into a class name)

4. Static member functions do not have a hidden this pointer and cannot access any non-static members.

5. Like ordinary members of a class, static members also have access levels of public, protected, and private, and can also have return values.

3. Implement a class and calculate how many class objects are created in the program

class A{
public:
     A() {++_scount;}
     A(const A& t) {++_scount;}
     static int GetACount() { return _scount;}
private:
     static int _scount;
};

int A::_scount = 0;

void TestA(){
     cout<<A::GetACount()<<endl;
     A a1, a2;
     A a3(a1);
     cout<<A::GetACount()<<endl;
}

We analyze it, first create two objects a1, a2, at this time _scount member variable ++ twice, the value is 2, then create a3, call the copy constructor, make _scount ++ again, At this point, the value of _scount is 3, and we have created exactly 3 objects.

operation result:

4. Can a static member function call a non-static member function?

No, there is a hidden this pointer in a non-static member function, which can only be called by the object, and a static member function cannot pass parameters to its this pointer.

5. Can a non-static member function call a class's static member function?

Yes, the static member functions of a class are public to all objects and can be accessed directly, so they can be called directly by non-static member functions.

3. C++11's member initialization new gameplay.

introduce:

C++11 supports initialization and assignment of non-static member variables when they are declared, but it should be noted that this is not initialization, but the default value for the declared member variable.

example:

class B{
public:
	B(int b)
		:_b(b)
	{}
	int _b;
};
class A{
public:
	void Print(){
		cout << a << endl;
		cout << b._b << endl;
		cout << sizeof(p) << endl;
	}
private:
	// 非静态成员变量,可以在成员声明时给缺省值。
	int a = 10;
	B b = 20;
	int* p = (int*)malloc(4);
	static int n;
};

int A::n = 10;

int main(){
	A a;
	a.Print();
	return 0;
}

operation result:

 4. Tomomoto

1. Function

Friend provides a way to break through encapsulation, and sometimes provides convenience, but Friend will increase the coupling degree and destroy the package, so Friend should not be used more often.

2. Friend function

(1). Why do you need friend functions?

If we need to overload <<, use it directly in the class: ostream&  operator<<(ostream&  _ cout) , overload, after overloading, we will find that it is: object<<cout when calling , because non- Static class member functions all have hidden this pointers, so this is bound to happen, which is different from the actual cout form, so we can't overload it in the class, so try to overload it outside the class into a global function:  ostream&  operator<<(ostream&  _ cout, class type object), then we call it again as : cout<< object, but because the overloaded function is a global function outside the class, it cannot access the class In order to solve this problem, we introduced a friend function. We only need to make a friend declaration of the overloaded function in the class, then it will not be affected by the access qualifier, thus fulfilling our needs. .

(2). Declaration method.

A friend function can directly access the private members of a class. It is an ordinary function defined outside the class and does not belong to any class, but it needs to be declared inside the class, and the friend keyword needs to be added when declaring it.

example:

class Date {
	friend ostream& operator<<(ostream& _cout, const Date& d);
	friend istream& operator>>(istream& _cin, Date& d);
public:
	Date(int year = 1, int month = 3, int day = 3)
		: _year(year)
		, _month(month)
		, _day(day)
	{}

private:
	int _year;
	int _month;
	int _day;
};
ostream& operator<<(ostream& _cout, const Date& d){
	_cout << d._year << "-" << d._month << "-" << d._day;

	return _cout;
}
istream& operator>>(istream& _cin, Date& d){
	_cin >> d._year;
	_cin >> d._month;
	_cin >> d._day;
	return _cin;
}

int main(){
	Date d;
	cin >> d;
	cout << d << endl;
	return 0;
}

(3) Features:

1. A friend function can access the private and protected members of the class, but it is not a member function of the class itself.

2. Friend functions cannot be modified with const.

3. Friend functions can be declared anywhere in the class, and are not restricted by class access qualifiers.

4. A function can be a friend function of multiple classes.

5. The calling of friend function is the same as the calling and principle of ordinary function.

3. Friend class

(1). Concept

All member functions of a friend class can be friend functions of another class and can access non-public members of another class.

(2). Example

In the member function of the date class, you can directly access the private member variables of the time class.

class Date; // 前置声明
class Time {

	friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成员变量

public:
	Time(int hour = 1, int minute = 2, int second = 3)
		: _hour(hour)
		, _minute(minute)
		, _second(second)
	{}

private:
	int _hour;
	int _minute;
	int _second;
};

class Date {

public:
	Date(int year = 1900, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}

	void SetTimeOfDate(int hour, int minute, int second) {
		// 直接访问时间类私有的成员变量
		_t._hour = hour;
		_t._minute = minute;
		_t._second = second;
	}

private:
	int _year;
	int _month;
	int _day;
	Time _t;
};

(3). Characteristics

1. Friend relationship is one-way and not commutative.

eg: A is a friend class of B, member functions in A can access non-public members in B, but member functions in B cannot access non-public members in A.

2. Friendship cannot be passed.

eg: If B is a friend of A and C is a friend of B, it does not mean that C is a friend of A.

5. Inner class (understand)

1. Concept

If a class is defined inside another class, the inner class is called an inner class. Note that this inner class is an independent class at this time, it does not belong to the outer class, and it is not possible to call the inner class through the object of the outer class. Classes do not have any privileged access rights to inner classes.

2. Pay attention

The inner class is the friend class of the outer class. Pay attention to the definition of the friend class. The member function of the inner class can use the object of the outer class as a parameter to access all members of the outer class. (The outer class is not a friend of the inner class)

3. Features

1. The inner class can be defined in the public, protected and private of the outer class.

2. Note that the inner class can directly access the static and enumeration members in the outer class, without the object/class name of the outer class.

3.sizeof(outer class) = outer class, which has nothing to do with inner class.

4. Examples

class A{
private:
	static int k;
	int h;
public:
	class B{
	public:
		void foo(const A& a){
			cout << k << endl;//OK
			cout << a.h << endl;//OK
		}
	};
};

int A::k = 3;

int main(){
	A::B b;
	b.foo(A());
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_49312527/article/details/123796205