C++继承中同名非静态成员与静态成员的处理(学习笔记)

发布时间:2023年12月18日

非静态成员:

定义一个父类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();? //类名访问??通过作用域调用父类成员函数
}

文章来源:https://blog.csdn.net/L2757721107/article/details/135045305
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。