博客
关于我
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 pandas TimeStamps到夏令时的本地时间字符串
查看>>
Python pandas 数据清洗与数据绘图实战
查看>>
Python Pandas 用顶行替换标题
查看>>
Python pandas 通过 dt 访问器有效地将日期时间转换为时间戳
查看>>
Python Pandas-从DataFrame按类别绘制多个条形图
查看>>
Python Pandas:每月或每周拆分 TimeSerie
查看>>
python pandas中融化的对面
查看>>
python pandas从时间序列中提取唯一日期
查看>>
Python PyQt5 将不再显示此消息复选框添加到 QMessageBox
查看>>
Python PyQt5:如何使用 PyQt5 显示错误消息
查看>>
Python PYSFTP-以字符串/文本形式传递私钥,而不是传递文件路径
查看>>
Python pytest 面试题!
查看>>
Python pytz 时区函数返回一个相差 9 分钟的时区
查看>>
python rabbitmq实现简单/持久/广播/组播/topic/rpc消息异步发送可配置Django
查看>>
Python random和json模块
查看>>
Python random模块seed理解
查看>>
python range()函数
查看>>
Python rdflib可传递查询
查看>>
python redis 集群_python 搭建redis集群
查看>>
python redis连接,在Python中使用Redis连接池的正确方法
查看>>