定义一个父类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;//子类成员变量 100? ? cout << s.m_B?<< endl;//子类成员变量 float型 2000
}
调用父类的成员变量需加作用域
void test02()
{
?? ?Son s;
?? ?cout << s.Base::m_A << endl;//通过作用域调用父类成员变量 10? ? cout << 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();? //类名访问??通过作用域调用父类成员函数
}