C++ inheritance (2) - assignment conversion, hidden attributes and scope

Table of contents

1. Assignment and conversion of subclass and parent class objects

There are two other ways for subclass objects to assign parent class objects:

Summarize:

2. Scope of parent class and subclass

1. In the inheritance system, base classes and derived classes have independent scopes.

        example:

2. Scope practice

        Exercise 1:

Solution:

1. Assignment and conversion of subclass and parent class objects

Let’s look at a case first: assignment between variables

int main(){
	int a;
	double b = 10.22;

	a = b;    //赋值转换
	return 0;
}

        In the above code, there are two variables a and b. The types of these two variables are integer and floating point respectively, and variable b is assigned to variable a. The value of variable b is 10.22. During the process of assigning to variable a, A temporary variable is generated, and a copy of 10.22 is given to the temporary variable. Type conversion is performed in this temporary variable, 10.22-->10, and then the value of the temporary variable 10 is assigned to variable a. 

After learning the characteristics of inheritance, we will look at the assignment and conversion process of subclass and parent class objects through this case:

class Person {
public:
	void Print() {
		cout << "Person类对象的成员属性:" << endl;
		cout << _age << endl;
		cout << _name << endl;
		cout << _hight << endl;
		cout << _address << endl;
		cout << endl;
        }
public:
	int _age;
	string _name;
	int _hight;
	string _address="TaiYuan";

};

class Student:public Person{
public:
	int _className;
	string _grade;
};

int main(){
    Person p1;
	p1._name = "小曹";
	p1._age = 21;
	p1._hight = 172;
	p1.Print();

	Student s1;
	s1._name = "小王";
	s1._age = 22;
	s1._hight = 170;
	s1._grade = "大三";

	//将子类对象的成员值复制给父类对象
	p1 = s1;			
}

        At this time, the member value of the p1 object is the member value of s1, but p1 will not have the _grade, _className member variable values ​​​​created by the Student subclass. During the assignment operation, the subclass object will only reset the member values ​​​​it inherited. Assign back to the parent class object! ! !

 

 This is the assignment conversion of subclass objects to parent class objects - upward conversion is supported, but downward conversion is not supported.

        That is to say, the parent class object cannot be assigned to the subclass object, because the parent class object does not have the _classname and _grade member values ​​​​of the subclass object, then it cannot be assigned! ! !

There are two other ways for subclass objects to assign parent class objects:

Create a subclass object and initialize its members, while the parent class object is upconverted by reference. 

operation result: 


operation result: 

Summarize:

        Subclass objects can be assigned to objects of the parent class, pointers to the base class, and references to the base class. There is a vivid term here called "slicing" or "cutting". This means that the subclass will cut off the member values ​​inherited from the parent class and assign them to the parent class object/pointer/reference.

2. Scope of parent class and subclass

1. In the inheritance system, base classes and derived classes have independent scopes.

        example:
class Person {
public:
	void Print() {
		cout << "父类的Print函数:" << endl;
		cout << "姓名:" << _name << endl;
		cout << "年龄:" << _age << endl;
		cout << "性别:" << _sex << endl;
		cout << endl;
	                }
	int Add(int age=100) {
		return _age = ++age;
	}
public:
	int _age=26;
	string _name="王丽";
	string _sex="女";
};

class Student :public Person {
public:
	void Print() {
		cout << "子类的Print函数:" << endl;
		cout << "学号:" << _id << endl;
		cout << "性别:" << _sex << endl;
		cout << "班级:" << _ClassName << endl;
		cout << endl;
	            }
public:
	int _id=202001;
	string _ClassName="优秀2班";
	string _sex="男";
};


int main() {
	Person p;
	p.Print();	
	Student s1;
	s1.Print();	
	
	s1._age = s1.Add();	
	cout << "对象s1的成员变量_age值为:"<<s1._age << endl;

	s1.Person::Print();			

	return 0;
}

Code analysis: As can be seen from the code above, both the parent class and the subclass have a Print() member function, and both the subclass object and the parent class object call the Print() function. 

operation result: 

        From the results, we found that when the subclass object and the parent class object call the Print() function, they both call the Print() function in their own class, and the subclass does not call the parent class Print() function. 

        Then we can draw a rule from it: when there is a function with the same name in the parent class and the child class, and both types of objects call the function with the same name, the compiler will give priority to calling the function with the same name in the object's own class. If there is no function of this name in the object of this class, the compiler will look for the function of this name from the member functions inherited by the subclass from the parent class.

        Doesn't this feel a little familiar? Isn't this the case of variable assignment? The compiler uses local priority method. If it is not found locally, it will be searched globally.

Test code:

The above are the detailed steps for the compiler to call functions on subclass objects. 

Then there is a new question. What should I do if the subclass object wants to call the Print() function in the parent class?

        The general method will not work. After all, Print() in the subclass is there, and there is a "hiding" mechanism for the function of the same name in the parent class and the subclass. The subclass will hide the member functions inherited from the parent class. , which means that on the surface there is only one Print function in the subclass. Although the subclass has the Print function of the parent class, it is hidden by the subclass and will not be used unless absolutely necessary.

       

         If you just want to call Print() of the parent class, you have to add a scope qualifier before the call!

So hiding only applies to member functions of the parent class and subclasses that each have the same name! !


2. Scope practice

        Exercise 1:
class Person {
public:
	void Func() {
		cout << "Func():" << endl;
		cout << endl;
	            }
public:
	int _a;
	string _b;
};

class Student :public Person {
public:
	void Func(int i) {
		cout << "Func(int i)->:" << endl;
        	}
public:
	int _id;
	double _result;
};

int main() {
	Student s2;
	s2.Func();

What happens when the code is executed?

A: causing overloading B: causing overwriting C: hiding/redefining D: compilation error 

Exercise analysis:

        As can be seen from the above code: the Func function of the Person class is a function without parameters, while the Func function of the subclass Student is a function with parameters.
Based on this, if s2.Func(); the compiler will give priority to calling the Func function of this subclass by default. However, when calling, it was found that the Func function of the subclass requires parameters, and when object s2 is called, no actual parameters are passed in, so the result is: choose C and D: both hidden situations and compilation errors will occur.

        Summary description: Func() called by s2 did not pass parameters, causing the compiler to not find a Func function that conforms to no parameters and report a compilation error. In this case, the subclass hides the Func() inherited from the parent class. Functions with parameters, that is to say, what s2 wants to call is the member function inherited from the parent class, but it is hidden by the subclass, so it cannot be called, and a compilation error occurs. ,

Solution:
    //解决方法1:
	    s2.Person::Func();
	//解决方法2:
	    s2.Func(10);

Guess you like

Origin blog.csdn.net/weixin_69283129/article/details/132011160