成员函数的重载

http://www.techweb.com.cn/network/system/2017-06-24/2542705.shtml

1、成员函数的重载

1.1、C++中的成员函数有4种,分别是普通成员函数,virtual虚函数,const成员函数。

  • void func(int a)
  • virtual void func(int a);
  • void func(int a) const;

如果在一个类中,声明这四种函数,哪是重复定义?哪些是重载?其中(1)(2)是重复定义,故编译不能通过,而(3)与(1)(2)是不同类型的函数,是重载。

因为类中的函数,都会自动添加一个自身类指针this,所以

  • void func(int a);          ------>  void func(Base *this, int a)
  • virtual void func(int a); ------>  virtual void func(Base *this, int a)
  • void func(int a) const;  ------>  void func(const Base *this, int a) const

所以(3)可以和(1)(2)重载,因为参数有一个const

1.2、类的成员函数重载是在同一个类中有多个同名的方法,这些方法的参数类型、参数个数或者方法属性(const)不同。

#define _CRT_SRCURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;

class MyClass
{
public:
	MyClass(int a = 0):c(a) {};
	void go(int a) { cout << "go "; };
	void go(char a){ cout << "char go "; };
	void print()const//函数体中不能修改数据成员对象,否则报错
	{
		cout << "const " << c << endl;
	}
	void print()//函数体中可修改成员对象
	{
		c = 23;
		cout << "non-const " << c << endl;
	}
private:
	int c;
};
void main()
{
	MyClass my;
	my.go(1);
	my.print();  //non-const  23
	
	const MyClass myC;
	myC.print();  //const 0
	system("pause");
}

成员函数重载特征:

  • 相同的范围
  • 函数名字相同
  • 参数类型,个数,顺序不同[包括const参数和非const参数]
  • virtual关键字可有可无

2、成员函数的继承  

#define _CRT_SRCURE_NO_WARNINGS
#include <iostream>
using namespace std;

class Base
{
public:
	void func(int a) { cout << "Base::f(int a)" << endl; };
	virtual void go(int a) { cout << "virtual Base: go(int a) " << endl; }; //virtual void func(Base *this, int a)
};

class Deviced :public Base
{
public:
	void h(int a) { cout << "Deviced::h(int a)" << endl; };
};
void main()
{
	Base b;
	b.func(3);
	b.go(4);
	Deviced d;
	d.func(32);
	d.go(4);
	d.h(32);
	system("pause");
}

子类deviced d种继承了父类种的virtual void g(int a), vpid f(int a);

3、成员函数的覆盖

覆盖是指派生类重新实现[或者改写]基类地成员函数,其特征是:

  • 不同的作用域
  • 函数名称相同
  • 参数列表相同
  • 基类函数必须是虚函数----->覆盖是针对基函数的

Deviced d种重新定义了基类的虚函数成员virtual void g(int a);

#define _CRT_SRCURE_NO_WARNINGS
#include <iostream>
using namespace std;

class Base
{
public:
	void func(int a) { cout << "Base::f(int a)" << endl; };
	virtual void go(int a) { cout << "virtual Base: go(int a) " << endl; }; //virtual void func(Base *this, int a)
};

class Deviced :public Base
{
public:
	void h(int a) { cout << "Deviced::h(int a)" << endl; };
	virtual void go(int a) { cout << "Deviced Base: go(int a) " << endl; };
};
void main()
{
	Base b;
	b.func(3);
	b.go(4);
	Deviced d;
	d.func(32);
	d.go(4);
	d.h(32);
	system("pause");
}

4、成员函数的隐藏

隐藏是指派生类的成员函数遮蔽了与其同名的基类成员函数:隐藏是在子类中看不到父类的函数

隐藏/重定义:指的是派生类的成员函数隐藏了基类函数的成员函数。
在调用一个类的成员函数时候,编译器会沿着类的继承链逐步向上
查找函数的定义,如果找到了就停止查找了。如果一个派生类和一个
基类都有同一个同名函数,而编译器最后选择了派生类的函数,我们
就说这个派生类的成员函数隐藏了基类的成员函数,也就是阻止了编译器
继续向上查找函数的定义。

#define _CRT_SRCURE_NO_WARNINGS
#include <iostream>
using namespace std;

class Base {
public:
	virtual void f(float x) { cout << "virtual Base::f(float)" << x << endl; }
	void g(float x) { cout << "Base::g(float)" << x << endl; }
    void h(float x) { cout << "Base::h(float)" << x << endl; }
};

class Deviced :public Base
{
public:
	virtual void f(float x) { cout << "virtual Deviced::f(float)" << x << endl; }
	void g(int x) { cout << "Deviced::g(int)" << x << endl; }
	/*派生类的函数与基类的函数同名不同参,此时,无论有无vritual,*/
	void h(float x) { cout << "Deviced::h(float)" << x << endl; }
};
void main()
{
	Deviced d;
	Base *pb = &d;   //基类指针指向派生类
	pb->f(3.14f);    //覆盖 
	/*virtual Deviced::f(float):f是一个虚函数,派生类重写了这个虚函数
	不同的范围,函数名字相同,参数相同,是基函数
	派生类对象/指向派生类的指针:调用了子类的同名函数
	基类对象:调用基类中的函数
	*/
	pb->g(3.14f);     //Base::g(float)
	/*不同类中,不是重载;不是virtual不是覆盖,没关系
	基类指针只能访问基类g
	*/
	pb->h(3.14f);  //Base::h(float)
	Deviced *pd = &d;     //派生类指针调用派生对象 
	pd->f(3.14f);     //  virtual Deviced::f(float)
	pd->g(3.14f);     //Deviced::g(int)
	pd->h(3.14f);     //Deviced::h(float),隐藏是在子类中看不到父类的函数
	system("pause");
}

猜你喜欢

转载自blog.csdn.net/zhizhengguan/article/details/81433124
今日推荐