C++继承:同名成员、静态成员,处理方式大揭晓

继承是面向对象编程中的重要概念,子类可以继承父类的成员变量和成员函数,
但当子类和父类出现同名的成员时,就需要考虑如何访问。

继承同名成员处理方式

同名成员变量处理

  • 访问子类同名成员变量 直接访问即可
  • 访问父类同名成员变量 需要加作用域
    即:子类对象可以直接访问到子类中同名成员变量,但访问父类中的同名变量则需要通过子类对象加作用域来实现
    代码演示:
#include <iostream>
using namespace std;

class Base {
public:
	Base() {
		m_A = 100;
	}
	int m_A;
};
class Son :public Base {
public:
	Son() {
		m_A = 200;
	}
	int m_A;
};

//同名成员变量处理
void test01() {
	Son s;
	cout << "Sin 下的 m_A = " << s.m_A << endl;
	//如果通过子类对象,访问到父类中的成员变量,需要加作用域
	cout << "Base 下的 m_A = " << s.Base::m_A << endl;
}
int main() {
	test01();
	
	system("pause");
	
	return 0;
}

同名成员函数处理

  • 访问子类同名成员函数 直接访问即可
  • 访问父类同名成员函数 需要加作用域
    代码演示:
#include <iostream>
using namespace std;

class Base {
public:
	void func() {
		cout << "Base - func()调用" << endl;
	}
	//函数重载
	void func(int a) {
		cout << "Base - func(int a)调用" << endl;
	}
};

class Son :public Base {
public:
	void func() {
		cout << "Son - func()调用" << endl;
	}
};

//同名成员函数处理
void test02() {
	Son s;
	s.func(); //直接调用,调用的是子类中的同名成员函数

	//如何调用到父类中同名成员函数?
	//加作用域
	s.Base::func();

	//当子类与父类拥有同名的成员函数,子类会隐藏父类中所有版本的同名成员函数
	//如果想访问父类中被隐藏的同名成员函数,需要加父类的作用域 
	//s.func(100);//报错
	s.Base::func(100);

}

int main() {

	test02();

	system("pause");

	return 0;
}

在上面的演示代码中,有一个新的知识点:

  • 当子类与父类拥有同名的成员函数,子类会隐藏父类中所有版本的同名成员函数

隐藏

  • 在面向对象编程中,隐藏(hiding)是指子类定义了与父类同名的成员变量或者成员函数,使得子类中的同名成员隐藏掉父类中的同名成员。
  • 这种机制可以用于代码重构、防止冲突等方面。

也就是说:

  • 当子类与父类拥有同名的成员函数,子类会隐藏父类中所有版本的同名成员函数
    什么意思?
    在上面的代码演示中:看这两行代码:
	s.func(100);//报错
	s.Base::func(100);

在test02()中,使用第一行代码,会报错。
如果想访问父类中被隐藏的同名成员函数,需要加父类的作用域。

小结1

总结:

  1. 子类对象可以直接访问到子类中同名成员
  2. 子类对象加作用域可以访问到父类同名成员
  3. 当子类与父类拥有同名的成员函数,子类会隐藏父类中同名成员函数,加作用域可以访问到父类中同名函数

继承同名静态成员处理方式

静态成员和非静态成员出现同名,处理方式一致

  • 访问子类同名成员 直接访问即可
  • 访问父类同名成员 需要加作用域

静态成员

在讲解下面的内容时,如果不懂得静态成员的使用方式,将看不懂代码。如果你已经懂得如何使用静态成员,可跳过此内容。
静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员

静态成员分为:

  • 静态成员变量
  • 所有对象共享同一份数据
  • 在编译阶段分配内存
  • 类内声明,类外初始化
  • 静态成员函数
  • 所有对象共享同一个函数
  • 静态成员函数只能访问静态成员变量

静态成员分为两种访问方式:

  • 通过对象
  • 通过类名

对于同名静态成员,需要注意到静态成员是属于类的,而不是某个具体的对象。
因此,当通过对象来访问静态成员时,仍然满足上述同名成员的访问规则,优先调用子类中的同名静态成员。而当通过类名来访问静态成员时,则依据采用的作用域来访问该同名成员函数。

同名静态成员变量处理

与同名成员变量处理方式相同

代码演示:

#include <iostream>
using namespace std;
//继承中的同名静态成员处理方式
class Base {
public:
	static int m_A;
};
int Base::m_A = 100;

class Son :public Base {
public:
	static int m_A;
};
int Son::m_A = 200;

//同名的静态属性
void test01() {
	//1、通过对象访问
	cout << "通过对象访问:" << endl;
	Son s;
	cout << " Son  下 m_A = " << s.m_A << endl;//200
	cout << " Base 下 m_A = " << s.Base::m_A << endl;//100

	//2、通过类名访问
	cout << "通过类名访问:" << endl;
	cout << " Son   下 m_A = " << Son::m_A << endl;//200
	cout << " Base  下 m_A = " << Base::m_A << endl;//200
	//通过子类访问到父类的m_A,并且通过类名方式访问
	cout << " Base  下 m_A = " << Son::Base::m_A << endl;//200
}
int main() {

	test01();

	system("pause");

	return 0;
}

解释这条代码含义:

	cout << " Base  下 m_A = " << Son::Base::m_A << endl;//200

第一个::代表通过类名方式访问
第二个::代表访问父类作用域下
即:通过类名Son的方式访问父类作用域下的m_A

同名静态成员函数处理

与同名成员函数处理方式相同
代码演示:

#include <iostream>
using namespace std;
//继承中的同名静态成员处理方式

class Base {
public:
	static void func() {
		cout << "Base - static void func()调用" << endl;
	}
	//重载
	static void func(int a) {
		cout << "Base - static void func(int a)调用" << endl;
	}
};

class Son :public Base {
public:
	static void func() {
		cout << "Son - static void func()调用" << endl;
	}
};

//同名的静态成员函数
void test02() {
	//1、通过对象访问
	cout << "通过对象访问:" << endl;
	Son s;
	s.func();//Son - static void func()调用
	s.Base::func();

	//2、类名方式访问
	cout << "通过类名访问:" << endl;
	Son::func();
	Base::func();
	Son::Base::func();

	//加上父类作用域
	Son::Base::func(100);
}

int main() {

	test02();

	system("pause");

	return 0;
}

解释这条代码含义:

Son::Base::func(100);

为什么不能使用:

Son::func(100);//报错

跟第一部分的成员函数同理:
子类出现和父类同名静态成员函数,也会隐藏父类中所有同名成员函数
如果想访问父类中被隐藏同名成员函数,需要加父类的作用域进行访问

小结2

同名静态成员处理方式和非静态处理方式一样,只不过有两种访问的方式(通过对象 和 通过类名)

总结

综上所述,我们需要谨慎处理子类与父类之间的同名成员问题,以减少命名冲突和易混淆的情况,同时为代码编写过程中注入更多理性思考和准确性原则。希望本篇技术博客的内容能对各位读者有所启发和帮助。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值