博客
关于我
C++ 类的继承四(类继承中的重名成员)
阅读量:786 次
发布时间:2019-03-24

本文共 2074 字,大约阅读时间需要 6 分钟。

类继承中的重名成员问题是C++编程中常见但容易引发混淆的概念。面对子类与父类存在同名成员的情况,编译器如何处理?子类是否可以访问父类的同名成员?这一系列的问题背后其实隐藏着严格的规则和原则,这一篇文章将为你详细解答。

在C++中,当子类定义了与父类同名的成员时,编译器会为子类的这个成员开辟独立的内存空间。具体来说,子类对象中的重名成员会被当作独立的属性,优先于父类成员访问。因此,在子类中直接访问同名成员时,默认会访问子类的那个成员,而不再是父类的成员。对于父类的成员函数而言,只有在函数定义中明确使用子类命名空间时(例如PointA::y),才可以访问父类的成员。否则,子类函数调用会优先使用子类的成员。

这一规则背后的逻辑是基于类的对象管理模型。类似于Java中的引用,类的非静态成员函数会有一个隐含的对象指针参数。因此,子类对象调用父类成员函数时,实际上是将子类对象赋值给父类的对象指针。由于父类函数中的指针不能强行转换为子类对象,因此它们只能访问父类对象的成员。

接下来,我们看一个具体的示例来理解这一机制。假设定义了一个基类PointA,以及继承自PointA的子类PointB

class PointA {
public:
int x;
int y;
void PrintA() {
cout << "x=" << x << ";y=" << y << endl;
}
void PrintB() {
cout << "x=" << x << ";y=" << y << endl;
}
};
class PointB : public PointA {
public:
PointB() {
x = 3;
y = 8;
z = 7;
PointA::y = 11; // 在子类中访问父类的成员
}
int y;
int z;
void Test1() {
cout << "z=" << z << ";y=" << y << endl;
}
void PrintB() {
cout << "z=" << z << ";y=" << y << endl;
}
};

在子类PointB中定义了一个额外的属性z,并重新定义了PrintB()函数。需要注意的是,子类中的y成员因为和父类的y重名,所以在子类内部需要使用PointA::y来访问父类的成员。类似的,子类的成员函数可以通过明确使用父类名来调用父类的重名成员函数。

接下来,我们来看一下如何使用这些成员:

void ProtectA() {
PointB pb1;
pb1.PrintA(); // 调用子类的PrintA函数
cout << "----------------" << endl;
pb1.Test1(); // 调用子类的Test1函数
cout << "----------------" << endl;
pb1.y = 33; // 赋值子类的y成员
pb1.PointA::y = 44; // 通过明确使用父类名访问父类的y成员
pb1.PrintA(); // 再次调用子类的PrintA函数
cout << "----------------" << endl;
pb1.Test1(); // 再次调用子类的Test1函数
}

可以看到,在子类中访问父类重名成员需要使用PointA::来限定访问范围。这种方式可以避免因重名成员存在而产生的潜在歧义。

关于函数的重名情况:

void ProtectB() {
PointB pb1;
pb1.PrintB(); // 调用子类的PrintB函数
cout << "--------------------" << endl;
pb1.PointA::PrintB(); // 需要明确使用父类名调用父类的PrintB函数
}

在这种情况下,子类的PrintB()函数和父类的PrintB()函数是两个独立的函数。当在子类对象上直接调用PrintB()时,默认会调用子类的版本。如果需要调用父类的版本,则需要使用PointA::PrintB()

通过以上示例可以看出,C++对类继承中的重名成员问题采取了严格的处理方式。子类的成员会在编译时进行隐藏,只有在明确使用父类命名空间时才会访问父类的成员。这种机制可以避免因成员名称冲突而导致的麻烦,同时也为子类的扩展提供了更大的灵活性。

总的来说,理解C++中的重名成员处理规则是掌握面世级 OO程序语言的基础知识。正确理解这些规则,可以帮助开发者避免潜在的错误,并更好地利用类的继承特性。

转载地址:http://xxlkk.baihongyu.com/

你可能感兴趣的文章
RabbitMQ - 死信、TTL原理、延迟队列安装和配置
查看>>
PHP数据访问的多重查询(租房子查询)
查看>>
RabbitMQ - 如保证消息的可靠性?(消息确认、消息持久化、失败重试机制)
查看>>
RabbitMQ - 基于 SpringAMQP 带你实现五种消息队列模型
查看>>
php数组函数分析--array_column
查看>>
php数组去重复数据的小例子
查看>>
php数组实现:哈希 +双向链表
查看>>
PHP数组排序函数array_multisort()函数详解(二)
查看>>
php数组的几个函数和超全局变量
查看>>
PHP文件上传详解
查看>>
PHP文件锁
查看>>
php文本框输入制定文本,php – 当用户没有向文本框输入任何内容时...
查看>>
PHP时间戳和日期相互转换操作总结
查看>>
php时间戳知识点,php 时间戳函数总结与示例
查看>>
php更新数据库失败,php – 无法更新MySQL数据库
查看>>
php机器人聊天对话框,基于AIML的PHP聊天机器人
查看>>
PHP查找数组中最大值与最小值
查看>>
php查最大值,在PHP数组中查找最大值
查看>>
php标签筛选,关于PHP CodeIgniter框架中通过<a>标签和url做多条件分类筛选
查看>>
php根据年月日计算年龄
查看>>