非静态成员:
定义一个父类Base,子类Son
class Base
{
public:int m_A = 10;int m_B = 200;void fun(){cout << "父类函数" << endl;}void fun(int a){cout << a << endl;}
};
class Son : public Base
{
public:int m_A = 100;float m_B = 2000;void fun(){cout << "子类函数" << endl;}
};
1.当子类与父类拥有同名的成员变量时,子类将会隐藏父类中拥有同名的成员变量
void test01()
{
Son s;
cout << s.m_A << endl;//子类成员变量 100cout << s.m_B << endl;//子类成员变量 float型 2000
}
调用父类的成员变量需加作用域
void test02()
{
Son s;
cout << s.Base::m_A << endl;//通过作用域调用父类成员变量 10cout << s.Base::m_B << endl;//通过作用域调用父类成员变量 int型 200
}
2.当子类与父类拥有同名的成员函数,子类将会隐藏父类中拥有同名的成员函数
void test03()
{
Son s;
s.fun();//子类成员函数
}
调用父类的成员变量需加作用域
void test03()
{
Son s;s.Base::fun();//通过作用域调用父类成员函数
s.fun(10);//错误,函数中调用的参数太多 即:父类的重载版本也被隐藏s.Base::fun(10);//通过作用域调用父类成员函数
}
因此:只要是有相同名字的函数(不在乎是否重载,还是完全相同),父类的一切同名的成员函数都将被隐藏。
好处:子类调用与父类同名成员函数时,解决了二义性的问题(即子类的成员函数与父类的成员函数完全相同时,调用的是子类的成员函数,加作用域才调用的是父类的成员函数)
总结:
1.当子类与父类拥有同名的成员时,子类将会隐藏父类中拥有同名的成员。
2.子类对象通过加作用域的方式访问被隐藏的父类同名成员。
静态成员:
前提知识:
静态成员:静态成员不属于某个对象上,所有对象都共享同一份数据。
通过两者方式进行访问:1.通过对象进行访问 ;2.通过类名进行访问(需加作用域)。
原则:
1.静态成员变量创建时,类内声明,类外定义。
2.静态成员函数创建时,类内声明,类外定义 或 类内声明,类内实现。
同名静态成员处理方式和同名非静态成员一样:
当子类与父类拥有同名的静态成员时,子类将会隐藏父类中拥有同名的静态成员。
只是有两种方式:
通过对象 或者 通过类名 进行访问 再加作用域的方式访问被隐藏的父类同名成员。
class Base
{
public:static int m_A ;static int m_B ;static void fun(){cout << "A函数" << endl;}void fun(int a){cout << a << endl;}
};
int Base::m_A = 10;
int Base::m_B = 200;
class Son : public Base
{
public:static int m_A ;static float m_B ;static void fun(){cout << "B函数" << endl;}
};
int Son::m_A = 100;
float Son::m_B = 2000;
当子类与父类拥有同名的成员时,子类将会隐藏父类中拥有同名的成员
void test01()
{
Son s;
cout << s.m_A << endl;//通过对象
cout << s.m_B << endl;//通过对象
cout << Son::m_A << endl;//通过类名
cout << Son::m_B << endl;//通过类名
s.fun();//通过对象
Son::fun();//通过类名
}
调用父类的成员需加作用域
void test02()
{
Son s;
cout << s.Base::m_A << endl; //对象访问 通过作用域调用父类成员变量
cout << s.Base::m_B << endl; //对象访问 通过作用域调用父类成员变量//第一个:: 代表 类名访问 第二个:: 代表 访问父类作用域下
cout << Son::Base::m_A << endl; //类名访问 通过作用域调用父类成员变量
cout << Son::Base::m_B << endl; //类名访问 通过作用域调用父类成员变量
s.Base::fun(); //通过作用域调用父类成员函数
Son::Base::fun(); //类名访问 通过作用域调用父类成员函数
}