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

你可能感兴趣的文章
python和java哪个更值得学——来自知乎高赞回答
查看>>
python和c混合编程 github_在pycharm中使用git版本管理以及同步github的方法
查看>>
python命名空间更改_Python模块xml.etree.ElementTree自动修改xml命名空间键
查看>>
Python命名中尾随下划线有什么好处?
查看>>
Python启动脚本
查看>>
Python听写汇总结果
查看>>
python吊打Excel?屁!那是你不会用!
查看>>
Python合并两张图片 | 先叠透明度再合并 (附Demo)
查看>>
python各进制的表述与转换
查看>>
python各种库安装
查看>>
python可视化matplotlib_如何使用Python中最强大的可视化工具Matplotlib?
查看>>
python可维护性_使用这7大神器,让你的Python 代码更容易于维护
查看>>
Python只运行一次while循环
查看>>
python变量的详细教程_Python零基础入门教程之语法入门[变量](第二期)
查看>>
Python变量命名方法-ChatGPT4o作答
查看>>
Python变量与运算符
查看>>
Python变量/运算符/函数/模块/string
查看>>
python发送邮件的时候出现 error (535, b‘5.7.3 Authentication unsuccessful‘) 解决方法
查看>>
python系列【仅供参考】:python flask框架 debug功能
查看>>
python发送notes邮件_使用python在Lotus Notes中发送邮件
查看>>