函数隐藏:
隐藏也是只有在继承或者派生中才可能出现的情况,隐藏是指派生类的函数屏蔽了其基类的函数。注意只要派生类中的函数名与其基类中的函数名相同,基类函数将会被屏蔽。注意隐藏方法无法实现多态性。
成员隐藏:如果在派生类中新增一个与基类成员同名的成员,那么通过派生类访问该成员时,默认访问的是派生类自己新增的成员;这就是成员隐藏
如果想访问从基类中继承的同名成员,需要加上作用域 :基类名::同名成员名
#include <iostream> using namespace std; //基类 class base { public: int data1; void func() { data1 = 10; data3 = 20; cout<<"基类func()"<<endl; cout << "data1="<<data1<<" "<< "data3="<<data3<<endl; } protected: int data2; private: int data3; }; //派生类 class derive : public base//公有继承 { private: int data1; public: void func() { data1 = 5;//访问自己新增的data1 data2 = 20;//保护成员在派生类中可直接访问 cout<<"派生类func()"<<endl; cout << "data1="<<data1<<" "<< "data3="<<data2<<endl; } }; int main() { derive d{}; d.func(); d.base::func(); return 0; }
函数覆盖/重写 override
覆盖(override)是指派生类/子类重新定义基类/父类的虚函数。
重新定义的函数与被覆盖的虚函数的函数名和参数列表和返回值类型都要一样,只是函数的内部实现不同。为了提高代码的可读性,我们建议在派生类的覆盖函数后面加上关键字 override修饰,
其实还有一个功能,让编译器帮我们检测该覆盖函数头是否写对了。派生类的覆盖函数自动成为虚函数,无论你加不加 virtual关键字,意味着如果有另外的类继承这个派生类,那么它的派生类还可以继续覆盖这个函数。
如果某个虚函数不希望被它的派生类继续覆盖,可以加上关键字 final修饰(写在函数头后面)
如果某个类不希望被继承,也可以加上关键字 final修饰(写在类名后面)#include <iostream> using namespace std; class base { public: base(int d1,int d2) { data1 = d1; data2 = d2; cout << "base构造" << endl; } //虚析构函数 virtual ~base() { cout << "base析构" << endl; } int get_data2()const { return data2; } virtual void show() const { cout << "data1=" <<data1 << ",data2=" << data2 << endl; } protected: int data1; private: int data2; }; class derive : public base { public: //派生类有3个成员,派生类传3个参数 derive(int d1,int d2,int d3) : base{d1,d2} { data3 = d3; cout << "derive构造" << endl; } derive(const derive&other):base{other} { data3 = other.data3; } ~derive() { cout << "derive析构" << endl; } derive& operator=(const derive& other) { base::operator=(other);//调用基类的拷贝赋值给 data1,data2赋值 data3 = other.data3; return *this; } virtual void show() const override final { cout << "data1=" <<data1 <<",data2="<<get_data2()<<",data3=" << data3 <<endl; } private: int data3; }; void func(base *p) { p->show(); delete p; } int main() { base * p; p = new derive{1,2,3}; func(p); p = new base{15,18}; func(p); return 0; }
函数重载 overload
在同一个作用域内,定义多个同名函数,但是它们的参数不同(参数个数不同或类型不同)这就是函数重载;这些函数之间互为重载函数。注意与函数的返回值类型无关,重载必须在同一个类中。
#include <iostream> using namespace std; int Abs(int x) { cout << "int" <<endl; if(x < 0) return -x; else return x; } long int Abs(long int x) { cout << "long int" <<endl; if(x < 0) return -x; else return x; } long long int Abs(long long int x) { cout << "long long int" <<endl; if(x < 0) return -x; else return x; } float Abs(float x) { cout << "float" <<endl; if(x < 0) return -x; else return x; } //... int main() { int a = -12; long int b = -20; long long int c = -23; float d = -1.9; cout << Abs(a) << endl; //_Z3Absi(a) cout << Abs(b) << endl; cout << Abs(c) << endl; cout << Abs(d) << endl; return 0; }