[C++] Classes and Objects

Time:2023-10-18

[C++] Classes and Objects


I. Preamble

As usual, let’s start with a recap of the last issue: last issue we focused on the six major C++ classes in theDefault Member Functionsand took it upon himself to implement adate classI’m sure you’ve learned a lot about classes in C++. This is the last installment of classes and objects, and it’s finally coming to an end.[C++] Classes and Objects

Without further ado, let’s eat!!!!

II. Initializing the list

2.1 Introduction

Let’s take a look at the code below:

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

private:
	const int _year;
	const int _month;
	const int _day;
};
int main()
{
	Date d;
	return 0;
}

[C++] Classes and Objects

When we compile our code, we find that the compiler reports a bunch of errors. There are two main reasons for reporting errors[C++] Classes and Objects

1、The const variable definition requires ainitialization

2、Const variables cannot be used asleft value

Hey, some of you may be wondering: didn’t we initialize the const member variable in the constructor? In fact, in the constructorin-functionWhat is performed is not initialization, butassign a value to somethingoperation. Because of theInitialization can only be initialized onceand multiple assignments can be made within the constructor.

For this reason, so the compiler reports the above two errors. So what to do? As we all know.Initialization is done in thedefinevariables, and where is that variable defined? The answer is:Initialization list

2.2 Concept

inC++in which the initialization list can be thought of as the member variabledefineThe place.

Initialization list: starts with acolon (punct.)Starting with acomma (punct.)separated by a list of data members, with each “member variable” followed by a variable that is placed in thebracesin the initial value or expression. Examples are as follows:

class Date
{
public:
	Date(int year = 2023, int month = 1, int day = 1)
		:_year(year) //initialization list, is where each member variable is defined and can be initialized
		,_month(month) //initialize member variable _month with the value of month
		,_day(day)
	{}

private:
	//Declaration of member variables
	const int _year = 0; 
	const int _month = 0;
	const int _day = 0;
};
int main()
{
	Date d;
	return 0;
}

2.3 Cautions

  1. Variables can only be initialized once, so each member variable can only appear once in the initialization list
  2. When a class contains the following members, they must be initialized by placing them in the initialization list position[C++] Classes and Objects
    class A
    {
    public:
    	A(int a) //explicitly define the constructor, do not automatically generate the default constructor
    		:_a(a)
    	{}
    private:
    	int _a;
    };
    class B
    {
    public:
    	B(int a, int ref)
    		:_a(a) //call parametric constructor initialization
    		, _ref(ref) //initialize reference variables
    		, _n(10) //initialize const variables
    	{}
    private:
    	A _a; // class without default constructor
    	int& _ref; // reference variable
    	const int _n; // const variable
    };
  3. It is recommended to initialize using the initialization list as much as possiblebecause the initialization list is a member variabledefineplace, whether you write it explicitly or not.Each member walks the initialization list
    class Time
    {
    public:
    	Time(int hour = 0)
    		:_hour(hour)
    	{
    		cout << "Time()" << endl;
    	}
    private:
    	int _hour;
    };
    class Date1
    {
    public:
    	Date1(int day)
    		:_day(day) //initialize using the initialization list
    		,_t(day)
    	{}
    private:
    	int _day;
    	Time _t;
    };
    
    class Date2
    {
    public:
    	Date2(int day)
    	{
    		_day = day; //assignment inside the constructor
    		_t = day;
    	}
    private:
    	int _day;
    	Time _t;
    };
    int main()
    {
    	Date1 d1(3);
    	cout << "-----------------------" << endl;
    	Date2 d2(3);
    	return 0;
    }

    [C++] Classes and Objects

  4. C++11Support for giving the statement at thedefault value, this default value is the one given to the initialization list. If the initialization list is not explicitly given a value, this default value is used; if it is explicitly given, it is initialized with the value given.

  5. The initialization list initializes member variables in the same order as they are declared., independent of the order in which the lists are initialized. As a small example[C++] Classes and Objects

    class A
    {
    public:
    	A(int a)
    		:_a1(a) //initialize the list in the same order as declared, i.e. also initialize _a2 before _a1
    		, _a2(_a1) // So what happens here when you initialize _a2 with _a1? What is the value of _a1
    	{}
    	void Print() {
    		cout << _a1 << " " << _a2 << endl;
    	}
    private:
    	// Declaration of member variables, first _a2 then _a1
    	int _a2;
    	int _a1;
    };
    int main() {
    	A aa(1);
    	aa.Print();
    }

    The output of the above code is1 Random values

    Parsing:Since _a2 is declared before _a1, _a2 will be initialized before _a1, so _a2 is initialized when _a1 is still a random value, so _a2 will be initialized to a random value, and then _a1 will be initialized to 1.


    We can also use debugging to observe the initialization order, as shown below:[C++] Classes and Objects


Three. explicit Keyword

       constructorNot only can you construct and initialize objects, forsingle parameterorAll have default values except the first parameter, which has no default value.constructor that also has theimplicit type conversionThe roles are as follows:

class Date
{
public:
    // 1. Single-parameter constructors with implicit type conversion
	Date(int year)
		:_year(year)
	{}

	//2. Although there are multiple parameters, the last two parameters can be passed without type conversion.
	// Modifying the constructor with explicit disables type conversion.
    //explicit Date(int year, int month = 1, int day = 1)
	//: _year(year)
	//, _month(month)
	//, _day(day)
	//{}
	
	Date& operator=(const Date& d)
	{
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2022); //Initialize d1 with a single-parameter constructor

	// Assign a value to a date object with a plastic variable.
	// The actual compiler behind the scenes constructs an anonymous temporary object with 2023, which is then used to assign a value to the d1 object.
	d1 = 2023; 
	return 0;
}

[C++] Classes and Objects

Like the one above.Left and right sides of the operatorType mismatchThe process of processing behind the compiler during arithmetic operations is calledimplicit type conversion


But.Such code tends to be poorly readableWe prefer to write code with the same type on both the left and right sides, so is there any way toprohibitionWhat about implicit type conversion by the compiler? There is.Explicit keywords

utilizationexplicitModifying the constructor will disable implicit type conversion of the constructor. It’s easy, just add the constructoraheadJust add explicit, and we won’t demonstrate it here.

Four. static members

4.1 Concepts

withstaticMember variables that are modified are calledstatic member variable; member functions modified with static are calledstatic member function. Static member variables must be in theoutside the categoryPerform initialization.

class A
{
	static int GetCount() //static member function
	{
		return count;
	}
private:
	static int count; //static member variable
};

int A::count = 10; //static member variables to be initialized outside the class

4.2 Characterization

  1. Static members are shared by all class objects, do not belong to a specific object, and are stored in thestatic area
  2. Static member variables mustIn-class declarations, out-of-class definitions. No need to add the static keyword when defining, the class is just declaring the
  3. Static members of a class can be created with the Class name::Static members orObject name. Static members access
  4. Static member functions do not have a hiddenthis pointerCannot access any non-static members
  5. Static members are also members of the class, subject to public, protected, and private access qualifiers.
     

Minor issues:Can a static member function call a non-static member function? And vice versa?


Question Answer:The answer is no.Static member functions cannot call non-static member functions.because static member functions do not have a hidden this pointer, while non-static member functions need to be passed thethis pointerto call. However, theNon-static member functions can call static member functions, because static member functions are characterized byNo this pointerTherefore, the call can be made directly.


V. Yuan Yuan

5.1 Concepts

In C++, in order toencapsulationWe generally declare member variables as [privatePrivate] private, allowing access to member variables only within the class. But sometimes we need to access member variables within theoutside the categoryAccessing these member variables, at this point, can be done in two ways: 1. Declaring the member variables as [public] Shared; 2. Utilizationfriend

Tomodachi provides a way to break out of encapsulation and facilitate the writing of code. Tomoyo is categorized intoYouyuan class (of birds)andpalindrome function (math.)When a function/class is declared as a friend function/class of a class, the function/class accesses a member of the class.not subject to access qualifiers. Here’s how functions/classes are declared as friends, using thefriend keyword[C++] Classes and Objects

class A
{
	friend void GetCount(const A& a); // Declare the global function GetCount as a friend function of class A.
	friend class B; // declare class B as a friend class of class A
private:
	int count = 10;
	int num = 20;
};

class B
{
public:
	void GetNum(const A& a)
	{
		cout << a.num << endl; // private members of class a can be accessed in class b
	}
};
void GetCount(const A& a)
{
	cout << a.count << endl; // can access private members of class A
}

int main()
{
	A a;
	B b;
	GetCount(a);
	b.GetNum(a);
	return 0;
}

Tip:While Tomodachi provides convenience, Tomodachi increases the number ofcoupling (physics), destroying the encapsulation of the program, so the use of friendlies is not recommended.

5.2 Friends function

Friends functions are generally used asStream extraction operator >>as well asStream insertion operator <<The overloading of these two operators is special and cannot be overloaded as member functions.

class Date
{
public:
	Date(int year = 2023, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	// If overloaded as a member function of Date, the first argument is the hidden this pointer, but cout is an object of the ostream class, and the first argument should be of type ostream, contradicting each other.
	// ostream& operator<<(const Date& d);   
private:
	int _year;
	int _month;
	int _day;
};

// Overloaded as a global function so that the first argument is of type ostream.
const ostream& operator<<(const ostream& out, const Date& d)
{
	Out < < d. _year < < "years" < < d.m onth < < "month" < < d.d ay < < "day";
	return out;
}

int main()
{
	Date d;
	cout << d; // Overload the stream insertion operator so that it can output date classes. 
	return 0;
}

The question then arises, since it can’t be declared as a member function, how are we going to access Date’s in the global functionPrivate membersAnd?[C++] Classes and Objects

This is where you have to use the friendlies we talked about above, declaring operator<< as the Date class’palindrome function (math.)After that, the code runs successfully:

class Date
{
public:
	Date(int year = 2023, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{}
	friend ostream& operator<<(ostream& out, const Date& d); // Declare the operator<< global function as a friend function of the Date class
private:
	int _year;
	int _month;
	int _day;
};

[C++] Classes and Objects

caveat

  • A friend function can access private members of a class, which are defined outside of the classordinary function (math.)Libyan Arab JamahiriyaNeeds to be declared inside the classThe declaration needs to be accompanied by thefriendKeywords.
  • A friend function cannot be modified by constThe const can only modify member functions.
  • Friends can be declared anywhere in the class definition without class access qualifiers.
  • A function can be a friend function of more than one class

5.3 Youyuan class

Friendly metaclasses in thepossessmember functions can all access another class’sNon-public members. The friend meta-relationship isuni-directionalThe.non-exchangeable. For exampleB is a friendly metaclass of A, all member functions in B can access private members in A, but member functions in A can’t access private members in B. An example is as follows:

class A
{
	friend class B; //define B to be a friend class of A

	void GetSum(B& b)
	{
		cout << b.sum << endl; //there will be an error here, the member function of class A can't access the private member of class B, it's not exchangeable
	}
private:
	int count = 20;
};

class B
{
	void GetCount(A& a)
	{
		cout << a.count << endl; // By compilation, B is a friendly class of A, and member functions in B can access A's private members.
	}
private:
	int sum = 10;
};

The above program will report the following error when compiled[C++] Classes and Objects

[C++] Classes and Objects


        Friendship meta-relationships are also not transitive. For example, if C is a friend class of B and B is a friend class of A, it is not possible to show that C is a friend of A. An example is as follows[C++] Classes and Objects

class A
{
	friend class B; //define B to be a friend class of A
private:
	int a_sum = 10;
};

class B
{
	friend class C; //define C as a friend class of B
private:
	int b_sum = 20;
};

class C
{
	void GetBSum(B& b)
	{
		cout << b.b_sum << endl; // compiles through, C is a friendly class of B
	}
	void GetASum(A& a)
	{
		cout << a.a_sum << endl; //Here the compiler will report an error, C is not a friend class of A, it cannot access private members, and the friendship relationship is not transitive
	}
private:
	int c_sum = 30;
};

The above program will report the following error when compiled[C++] Classes and Objects 

[C++] Classes and Objects


VI. Internal Classes

A class can be defined not only globally but also inside another class. We call a class defined inside a class ainternal class. The following class B is an inner class:

class A //A is called an external class
{
public:

	class B // Class B is defined inside class A and is called an inner class.
	{
	private:
		int sum; //member variable of class b
	};

private:
	int count; // member variable of class a
};

An inner class is aIndependent ClassesIt is not part of the external category, moreYou can’t access the members of an inner class through an object of the outer class.. The outer class does not have any special access to the inner class. There are two specific manifestations of this[C++] Classes and Objects

  • An inner class can be defined anywhere in an outer class and is not subject to the access qualifiers of the outer class.
  • sizeof(external class) = external class, nothing to do with internal class

        An inner class is a friend class of an outer class, the inner class can access all members of the outer class through the objects of the outer class. However, the external class is not a friend class of the internal class and has no right to access the private members of the internal class.

class A //A is an external class
{
public:

	class B //B is an inner class
	{
		int GetACount(A& a)  
		{
			return a.count; // can access private members of external classes
		}
	private:
		int sum; 
	};

	int GetBSum(B& b)
	{
		return b.sum; //this will report an error, external classes cannot access private members of internal classes
	}
private:
	int count; // member variable of class a
};

[C++] Classes and Objects

An inner class can directly access a foreign class in thestatic member, the object/class name of the external class is not required, as follows[C++] Classes and Objects

class A //A is an external class
{
public:

	class B //B is an inner class
	{
		int GetACount()  
		{
			return _count; // you can directly access static member variables of external classes without class name/class object
		}
	private:
		int sum; 
	};

private:
	static int _count; // static member variable in A
};

int A::_count = 10; //initialize outside the class

VII. Anonymous objects

C++ supports the fact that we don’t name objects; such objects we callanonymous object, which is defined in the following manner:

int main()
{
	// object type +(): create an anonymous object
	A(); // here is the creation of an anonymous object A
	return 0;
}

The declaration cycle for anonymous objects is only available in thecurrent lineThe destructor is automatically called at the end of the current line to destroy it:[C++] Classes and Objects

Anonymous objects haveconstant property, i.e., no changes can be made to member variables in anonymous objects:

int main()
{
	A().count = 10; //compiler error: expression must be modifiable left value
	return 0;
}

An anonymous object can be giventake an aliasThis way you canextendThe declaration cycle for anonymous objects:

int main()
{
	// Alias an anonymous object
	const A& cla1 = A(); //note: here it must be a const reference, because anonymous objects have constancy and permissions cannot be enlarged
	cout << "The program is about to end" << endl;
	return 0;
}

[C++] Classes and Objects

Anonymous objects are often used in situations where you only need to call a member function of a class, and you canSimplify the writing of our code. Examples are as follows[C++] Classes and Objects

class Solution //Solution is used to find the sum of two numbers.
{
public:
	int Sum_Solution(int x,int y) //return the sum of two numbers 
	{
		return x + y;
	}
};

int main()
{
	// Do not use anonymous objects
	Solution s1; //To define a class object first, this object is just used to call the method
	s1.Sum_Solution(2, 2); //then go back to calling the member function

	// Use of anonymous objects
	Solution().Sum_Solution(2, 3); // code is simpler
}

Does the Solution class above look familiar? Yes, it is when we use C++ forDo homeworkWhenever you can meet it[C++] Classes and Objects[C++] Classes and Objects


 Above, that’s all for this issue🌸

It’s not easy to make. Can you give me a like before you go?🙏

Recommended Today

uniapp and applet set tabBar and show and hide tabBar

(1) Set the tabBar: uni.setTabberItem({}); wx.setTabberItem({}); indexnumberisWhich item of the tabBar, counting from the left, is indexed from 0.textstringnoButton text on tabiconPathstringnoImage PathselectedIconPathstringnoImage path when selectedpagePathstringnoPage absolute pathvisiblebooleannotab Whether to display uni.setTabBarItem({ index: 0, text: ‘text’, iconPath: ‘/path/to/iconPath’, selectedIconPath: ‘/path/to/selectedIconPath’, pagePath: ‘pages/home/home’ }) wx.setTabBarItem({ index: 0, text: ‘text’, iconPath: ‘/path/to/iconPath’, selectedIconPath: ‘/path/to/selectedIconPath’, pagePath: ‘pages/home/home’ }) […]