C++中的继承、类内的函数重载、父类与子类之间的函数重写(多态和重定义)

继承:

  1. 在子类对象构造时,需要先调用父类的构造函数对继承自父类的成员进行初始化。
  2. 在子类对象析构时,需要最后调用父类的析构函数对继承自父类的成员进行清理。
  3. 如果子类中的成员变量和父类中的重名,就用域作用符,父类名::变量名,来对父类中的同名成员变量进行访问。

多态:为了能够对不同的继承类型,调用其下作用不同的同名函数,因此引入了多态的概念。

  1. 根据(父类)指针指向的实际的对象类型来判断重写函数的调用。
  2. 如果父类指针指向父类对象,则调用父类中定义的虚函数。
  3. 如果父类指针指向子类对象,则调用子类中定义的虚函数。
  4. 利用多态可以实现面向未来的开发。

间接赋值成立的三个条件:

  1. 函数参数中有一个形参,调用函数前定义一个实参。
  2. 建立关联:实参取地址传给形参。
  3. *p(形参,实参的地址),来间接修改实参的值。

重写和重载:

  1. 下面的基类和子类中的fun函数之间是什么关系?

  2. #include
    #include
    
    using namespace std;
    
    class Parent01
    {
    public:
    	Parent01();
    	~Parent01();
    
    public:
    	virtual void Virtual()
    	{
    		cout << "Parent01类的虚函数:Virtual()" << endl;
    	}
    	void fun()
    	{
    		cout << "Parent01类的无参函数fun" << endl;
    	}
    	void fun(int i)
    	{
    		cout << "Parent01类的有参函数fun" << endl;
    	}
    	virtual void fun(int i, int j)
    	{
    		cout << "Parent01类的虚函数:void func(int i, int j)" << endl;
    	}
    
    };
    
    Parent01::Parent01()
    {
    	cout << "Parent01类的构造函数" << endl;
    }
    
    Parent01::~Parent01()
    {
    	cout << "Parent01类的析构函数" << endl;
    }
    
    class Children01:public Parent01
    {
    public:
    	Children01();
    	~Children01();
    
    	void fun(int i,int j)
    	{
    		cout << "Children01类的虚函数fun(int i,int j)" << endl;
    	}
    
    	void fun(int i,int j,int k)
    	{
    		cout << "Children01的函数void fun(int i,int j,int k)" << endl;
    	}
    
    private:
    
    };
    
    Children01::Children01()
    {
    	cout << "Children01类的构造函数" << endl;
    }
    
    Children01::~Children01()
    {
    	cout << "Children01类的析构函数" << endl;
    }
    
    
    void run01(Parent01* parent)
    {
    	parent->fun(0, 1);
    	//parent->Virtual();
    }
    
    void main01()
    {
    	Children01 child;
    	run01(&child);
    
    
    	//child.Parent01::fun();
    
    
    	Parent01 parent;
    	run01(&parent);
    
    	parent.fun(1, 2);
    	child.fun(1, 2);
    
    	child.Parent01::fun(1,2);
    }
    
    void main_001()
    {
    	main01();
    
    	system("pause");
    }
  3. 在使用子类对象,直接调用父类的无参fun()时,会报错,这是因为子类中没有重载函数接受0个参数。C++中的继承、类内的函数重载、父类与子类之间的函数重写(多态和重定义)_第1张图片

  4. 这时需要在fun()之前加上基类的域作用符,即采用child.Parent::fun()的形式才能调用。C++中的继承、类内的函数重载、父类与子类之间的函数重写(多态和重定义)_第2张图片

  5. 在父类中,定义其他的函数,进行调用是没有问题的。C++中的继承、类内的函数重载、父类与子类之间的函数重写(多态和重定义)_第3张图片

  6. 两个参数的虚函是virtual void fun(int i, int j),在子类与父类中的多态是正常工作的。C++中的继承、类内的函数重载、父类与子类之间的函数重写(多态和重定义)_第4张图片

  7. 想在子类中直接直接调用无参的fun(),而不报错。要在子类中对fun()进行重定义。C++中的继承、类内的函数重载、父类与子类之间的函数重写(多态和重定义)_第5张图片C++中的继承、类内的函数重载、父类与子类之间的函数重写(多态和重定义)_第6张图片

  8. 在同一个类(作用域、命名空间)内,定义多个函数名相同,形参不同的函数,是函数重载。
  9. 在不同类之间,定义同名、形参个数相同的函数,是函数重写。上边对无参fun()在基类和父类中的重写就是这个原理。

  10. 所以子类对象中的fun()和父类对象的fun()发生了名称覆盖。调用自己重写的的fun()和继承自父类的fun()都可以。C++中的继承、类内的函数重载、父类与子类之间的函数重写(多态和重定义)_第7张图片

  11. 函数的重写与重载:

    子类与父类中,不加virtual关键字的函数重写,叫做重定义。

  12. 函数重载:必须在同一个类中进行;子类无法重载父类中的函数,只能进行重定义,才能直接用子类对象(对自己定义好的该函数)进行调用,父类同名函数将被覆盖;重载是在类内进行的,是在编译期间,根据重载函数的参数个数和参数类型进行函数调用。

  13. 函数重写:分为重写和重定义。重写发生在父类与子类之间,并且父类和子类中的函数具有完全相同的函数原型;使用virtual声明的函数重写,会在父类指针调用时,根据指针指向的实际对象的类型,形成多态特性;如果不加virtual,叫作重定义

  14. 所以上边两参数的virtual void fun(int i, int j);即使函数重写,又是多态

  15. 父类中(类内),加不加virtual的各个func之间仍然是重载关系。

    函数重载:函数名相同,参数的个数和类型不同。不包含返回值。

    而且virtual是关键字,不是返回值。C++中的继承、类内的函数重载、父类与子类之间的函数重写(多态和重定义)_第8张图片

你可能感兴趣的:(C++中的继承,类内的函数重载,父类与子类之间的函数重写(多)