博客
关于我
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/

你可能感兴趣的文章
NASA网站曝严重漏洞,或将沦为黑客钓鱼网站?
查看>>
Nash:轻量级、安全且可靠的脚本语言
查看>>
NAS、SAN和DAS的区别
查看>>
NAS个人云存储服务器搭建
查看>>
NAS服务器有哪些优势
查看>>
NAT PAT故障排除实战指南:从原理到技巧的深度探索
查看>>
nat 网卡间数据包转发_你是不是从来没有了解过光纤网卡,它跟普通网卡有什么区别?...
查看>>
NAT-DDNS内网穿透技术,快解析DDNS的优势
查看>>
NAT-DDNS内网穿透技术,快解析DDNS的优势
查看>>
NAT-DDNS内网穿透技术,解决动态域名解析难题
查看>>
natapp搭建外网服务器
查看>>
NativePHP:使用PHP构建跨平台桌面应用的新框架
查看>>
nativescript(angular2)——ListView组件
查看>>
NativeWindow_01
查看>>
Native方式运行Fabric(非Docker方式)
查看>>
Nature | 电子学“超构器件”, 从零基础到精通,收藏这篇就够了!
查看>>
Nature和Science同时报道,新疆出土四千年前遗骸完成DNA测序,证实并非移民而是土著...
查看>>
Nature封面:只低一毫米,时间也会变慢!叶军团队首次在毫米尺度验证广义相对论...
查看>>
Nat、端口映射、内网穿透有什么区别?
查看>>
Nat、端口映射、内网穿透有什么区别?
查看>>