c++ day13 polymorphism, calculator class case (new creation object)

Posted by sivarts on Mon, 07 Mar 2022 14:28:28 +0100

1. Basic concepts

Polymorphisms fall into two categories

  • Static polymorphism: function overloading and operator overloading belong to static polymorphism and reuse functions
  • Dynamic polymorphism: derived classes and virtual functions implement runtime polymorphism

Difference between static polymorphism and dynamic polymorphism

  • Statically polymorphic function addresses have long been bound -- the function address is determined at the compilation stage
  • Late binding of dynamically polymorphic function addresses -- Determination of function addresses at runtime

Dynamic polymorphism condition

  1. Inheritance relationship
  2. Subclasses and superclasses have function overrides (that is, functions with the same name)

Dynamic polymorphic use

  1. A pointer or reference to a parent class points to a child class object

Void dospeak (School & S) / / the pointer or reference of the parent class points to the object of the child class
{
    s.index();

}

class school
{
public:
	//Virtual function (the parent class must be added, and the child class doesn't matter)
	virtual void index()
	{
		cout << "notice" << endl;
	 }
};

class teacher :public school
{
public:
	void index()
	{
		cout << "Teacher forward notice" << endl;
	}
};

class student :public school
{
public:
	void index()
	{
		cout << "Student forwarding notice" << endl;
	}
};

void dospeak(school &s)  //The pointer of the parent class or the object that references the execution subclass
{
	s.index();//Because the object of school class is used at this time, the address is bound early. It has nothing to do with the subclass of the incoming object. It runs the index() function in the parent class
}


//If you want to run the index function of which subclass you want to transfer, you must bind the function address late and do it in the running phase
//Add virtual before the parent function
void test()
{
	teacher t;
	dospeak(t);
	student s;
	dospeak(s);//Determine the address according to the transmission object
}

int main()
{
	test();
	system("pause");
	return 0;
}

 

2. In depth analysis of polymorphism (not easy to write, watch video lesson 136)

3. Calculator cases

Add two operands

Common writing

class school
{
public:
	int m_age;
	int m_num;
	int sum(string oper)    //Pass in symbols for judgment
	{
		if (oper == "+")
		{
			return m_age + m_num;
		}
		else if (oper == "-")
		{
			return m_age - m_num;
		}	
	}
};


void test()
{
	school s; string oper;
	
	s.m_age = 19; s.m_num = 23;
	cout << "Please enter a plus or minus sign" << endl;
	cin >> oper;
	cout << s.sum(oper) << endl;
}

int main()
{
	test();
	system("pause");
	return 0;
}

I wrote it myself.

Existing problem: if a new calculation function is added with a new class, in the case of using virtual functions, a new class must create an object to use the new function, and the old function must also create an object with the class where the function is located

class calculator
{
public:
	int m_age;
	int m_num;
	virtual int sum(string oper)    //Pass in symbols for judgment
	{
		if (oper == "+")
		{
			return m_age + m_num;
		}
		else if (oper == "-")
		{
			return m_age - m_num;
		}		
	}
};

class cal2 :public calculator
{
public:
	 int sum(string oper)
	{
		if (oper == "*")
		{
			return m_age * m_num;
		}
	}
};

void add(calculator &c,string &oper )
{
	c.sum(oper);
}

void test()
{
	cal2 c; string oper;
	calculator s;
	s.m_age = 119; s.m_num = 233;
	c.m_age = 19; c.m_num = 23;
	cout << "Please enter a symbol" << endl;
	cin >> oper;
	add(c, oper); add(s, oper);
	//cout << c.sum(oper) << endl;
	cout << s.sum(oper) << endl; //After the parent function becomes virtual   
	//It seems that the objects created by the parent and child classes can only call the functions of their own classes, and cannot call all functions directly from the child classes.
	
}

The teacher answered

Strong organization and high expansibility

Although each class can only call the functions of its own class, it is simple to implement

Key points: calculator *c = new add()// Here, the parent class creates a pointer and receives the address of a piece of memory opened up by new for the add class, which is equivalent to an object instantiated by the add class
/ / therefore, the condition that the pointer or reference of the parent class points to the object of the child class is satisfied

Because the function of the parent class is a virtual function, the call of each calculation function, C - > getResult () is determined by the type of the instantiated class.

virtual of subclass is not required and can be written or not

class calculator
{
public:
	int m_num1;
	int m_num2;
	virtual int getresult()
	{
		return 0;
	}
};

//Addition calculator class
class add :public calculator
{
public:
	virtual int getresult()
	{
		return m_num1 + m_num2;
	}
};

class sub :public calculator
{
public:
	virtual int getresult()
	{
		return m_num1 - m_num2;
	}
};
	

class mul :public calculator
{
public:
	virtual int getresult()
	{
		return m_num1 * m_num2;
	}
};

void test()
{
	calculator *c = new add(); //Here, the parent class creates a pointer and receives the address of a piece of memory opened up by new for the add class, which is equivalent to an object instantiated by the add class
	//Therefore, the condition that the pointer or reference of the polymorphic parent class points to the object of the child class is satisfied
	c->m_num1 = 10; c->m_num2 = 20;
	cout << c->getresult() << endl;  //It can only be used once
	delete c; //Remember to destroy
	c = new sub();   //Here we just destroy the memory data. c is still a pointer. Remember to add ()
	c->m_num1 = 10; c->m_num2 = 20;
	cout << c->getresult() << endl;  //It can only be used once
	delete c;
}

int main()
{
	test();
	system("pause");
	return 0;
}

Topics: C++ Back-end