派生类对象包含从基类继承类的数据成员,他们构成了“基类子对象”
基类中的私有成员,不允许在派生类成员函数中被访问,也不允许派生类的对象访问他们;
真正体现基类私有,对派生类也不开放其权限;
基类中的公有成员:
若是public继承,则成为派生类的公有成员,既可以在派生类成员函数中访问,
也可以被派生类的对象访问;
若是private继承方式,则只能供派生类成员函数访问,不能被派生类的对象访问;
#include <iostream> using namespace std; class B { public: void f() { cout << "in B::f()..." << endl; } }; class D1 :public B {}; class D2 :private B { public: void g() { cout << "in D2::g(),calling f()..." << endl; f();//私有继承时,基类接口在子类成员函数中可以使用; } }; int main() { cout << "in main()..." << endl; D1 obj1; cout << "calling obj1.f()..." << endl; D2 obj2; cout << "calling obj2.g()..." << endl; obj2.g(); //error f()为私有继承,所以obj2.f()//基类接口不允许子类对象调用; }
重写与重载的区别:
函数重载要求函数名字必须一样,函数的参数要求不一样;
而函数的重写则是函数名字和函数的参数必须都一样;
基类已定义的成员函数,在派生类中可以重新定义它,这被称为函数重写(override)
重写发生时,基类中该成员函数的其他重载函数都将被屏蔽,不能提供给派生类对象使用;
可以在派生类中使用using 类名::成员函数名;在派生类中恢复指定的基类成员函数(即去掉屏蔽),使它重新可以使用;
#include <iostream> using namespace std; class T {}; class B { public: void f() { cout << "B::f()\n"; } void f(int i) { cout << "B::f(" << i << ")\n"; } void f(double d) { cout << "B::f(" << d << ")\n"; } void f(T) { cout << "B::f(T)\n"; } }; class D1 :public B { public: void f(int i) { cout << "D1::f(" << i << ")\n"; } }; int main() { D1 d; d.f(10); d.f(4.9);//编译警告,会执行自动类型转换 //d.f();//被屏蔽,编译错误 //d.f(T());//被屏蔽,编译错误 //f()被重写,故无法访问基类中同名的成员函数;其成员函数会被屏蔽掉; return 0; }
如果想要派生类中依然可以访问基类同名的成员函数,可以恢复基类中成员函数,方法如下:
在派生类中添加using B::f;就可以实现;
class D1 : public B { public: using B::f;//使用using基类名::函数名;恢复基类函数 void f(int i) { cout << "D1::f(" << i << ")\n"; } };
怕什么真理无穷,进一寸有一寸的欢喜。---胡适