同名隐藏

隐藏:是指派生类的函数屏蔽了与其同名的基类函数,注意只要同名函数,不管参数列表是否相同,基类函数都会被隐藏。

using namespace std;
class Object
{
public:
	int _num;
	Object(int num):_num(num) {
		cout << " Object create" << endl;
	}
	Object() {
		cout << " Object create" << endl;
	}

	void fun(int x)
	{
		_num = x;
		cout << "Object ::fun()" << endl;
	}

};
class Base :public Object
{
public:
	int  _val;
	Base() { cout << "Create Base " << endl; }
	Base(int v) :Object(v), _val(v) {
		cout << "Create Base " << endl;
	}
	void  fun() {
		cout << "Base ::Fun()" << endl;
	}

};
int main()
{

	Base base1;
	Object obj1;
	Base* bp = &base1;
	bp->fun();//ok //函数名相同,同名隐藏,将基类的函数隐藏,
	bp-> fun(10);//error  //编译器无法识别,不可以像函数重载一样识别。(因为作用域不同,每个函数都在不同的类域中)
	bp-> Object::fun(10);//ok,有类域的限定符指定访问
	return 0;
}

代码结果:

bp->fun();//ok //函数名相同,同名隐藏,将基类的函数隐藏

lua 重名覆盖规则 同名覆盖_开发语言

以下测试代码结果:

Object* p = &base1; p->fun();

lua 重名覆盖规则 同名覆盖_c++_02


切片,p只指向Object类对象。


同名覆盖(重写)

同名覆盖,指的是在继承关系中,父类和子类的虚函数名、形参类别、返回类型相同,并是公有继承,派生类重写了这个函数。

是指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类对象调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。

using namespace std;
class Object
{
public:
	int _num;
	Object(int num):_num(num) {
		cout << " Object create" << endl;
	}
	Object() {
		cout << " Object create" << endl;
	}

	virtual void fun()
	{
		//_num = x;
		cout << "Object ::fun()" << endl;
	}

};
class Base :public Object
{
public:
	int  _val;
	Base() { cout << "Create Base " << endl; }
	Base(int v) :Object(v), _val(v) {
		cout << "Create Base " << endl;
	}
	
	virtual void  fun() {

		cout << "Base ::Fun()" << endl;
	}

};
int main()
{

	Base base1;
	Object obj1;
	Object* p = &base1;
	p->fun();//查虚表,调用的是Base的fun();
	p->Object::fun();//静态联编,调用指定基类的fun()函数。
	Base *ip=&base1;
	ip->fun() //同名隐藏。
	return 0;
}

p->fun();//查虚表,调用的是Base的fun(); 以下是输出结果:

lua 重名覆盖规则 同名覆盖_函数参数_03

p->Object::fun();//静态联编,调用指定基类的fun()函数。

lua 重名覆盖规则 同名覆盖_函数参数_04


ip->fun() //同名隐藏。

lua 重名覆盖规则 同名覆盖_派生类_05


一个小知识点:一个唯一的例外:

当父类和子类的函数返回值是其类型的指针和引用时(说明两个函数的返回类型是不同的),则也是同名覆盖!。

在这里插入代码片

函数的重载

在C++中可以为两个或两个以上的函数提供相同的函数名称,只要参数类型不同,或参数类型相同
而参数的个数不同, 称为函数重载。

在继承关系中,不存在父类和子类之间的函数的重载(作用域不同)

class Base 
public:
	int  _val;
	Base() { cout << "Create Base " << endl; }
	Base(int v) : _val(v) {
		cout << "Create Base " << endl;
	}
	
	virtual void  fun() {

		cout << "Base ::Fun()" << endl;
	}
	virtual int  fun(int x)
	{
		_val = x;
		cout << "Base ::Fun()" <<_val<< endl;
		return _val;
	}

};
int main()
{

	Base base1;
	Base* bp = &base1;
	bp-> fun(10);
	return 0;
}

lua 重名覆盖规则 同名覆盖_c++_06


以下情况得错误:参数表相同,返回值不同会报错:

lua 重名覆盖规则 同名覆盖_lua 重名覆盖规则_07


三者区别:

重载和重写的区别:

(1)范围区别:重写和被重写的函数在不同的类中,重载和被重载的函数在同一类中。

(2)参数区别:重写与被重写的函数参数列表一定相同,重载和被重载的函数参数列表一定不同。

(3)virtual的区别:重写的基类必须要有virtual修饰,重载函数和被重载函数可以被virtual修饰,也可以没有。

隐藏和重写,重载的区别:

(1)与重载范围不同:隐藏函数和被隐藏函数在不同类中。

(2)参数的区别:隐藏函数和被隐藏函数参数列表可以相同,也可以不同,但函数名一定同;当参数不同时,无论基类中的函数是否被virtual修饰,基类函数都是被隐藏,而不是被重写。