一、写在前面
1.上篇涉及内容
- C++的三种继承方式
- C++的访问权限
- 子类对象的构造过程和析构过程
详见:C++继承机制(上篇)
2.本篇涉及内容
- 子类成员和父类成员同名情况
- C++中函数隐藏、函数重写的概念区分
二、子类成员和父类成员同名情况
1.成员变量同名
class Person {
public:
Person(int age, string name) {
this->age = age;
this->name = name;
}
protected:
int age;
string name;
};
class Student : public Person {
public:
Student(int age, string name, int num) : Person(age, name) {
this->num = num;
}
int getAge() {
return this->age;
}
string getName() {
return this->name;
}
int getNum() {
return this->num;
}
private:
int age;
int num;
};
int main() {
Student* student = new Student(18,"kl",1002);
cout << student->getAge() << endl;
cout << student->getName() << endl;
delete student;
return 0;
}
子类从父类那边继承过来了age和name两个成员变量,但是子类自身有一个age成员变量,此时出现子类成员变量与父类成员变量同名的情况.
输出结果:
从C++继承机制(上)我们知道,构建子类对象时,会先调用父类构造器对子类继承过来的具有父类型特征的成员变量进行赋值,因此这里在父类构造器中给子类继承过来的age成员变量和name成员变量进行了赋值,这里相当于Student类中具有自身的两个成员变量:age、num,还有继承过来的两个成员变量:age、name,一共有4个变量,但是有两个同名,父类继承过来的age成员变量被"隐藏",这里输出的成员变量数据是子类自身的成员变量age(并没有在构造器被赋值,被赋值的是继承过来的父类成员变量age).
如何访问被隐藏的父类成员变量?
让getAge方法返回作用域为Person的成员变量值.
int getAge() {
return this->Person::age;
}
在变量前面加上父类的作用域,就可以从访问子类本身的成员变量改变为访问从父类继承过来的成员变量.
2.函数隐藏_hide
特点:子类中的函数名称与父类中的函数名称相同(只是函数名称相同,注意区分函数覆盖)
class Person {
public:
Person(int age, string name) {
this->age = age;
this->name = name;
}
void print() {
cout << "Person's age = " << this->age
<< "\nPerson's name = " << this->name << endl;
}
void print(int a) {
cout << a << endl;
}
protected:
int age;
string name;
};
class Student : public Person {
public:
Student(int age, string name, int num) : Person(age, name) {
this->num = num;
}
int getAge() {
return this->Person::age;
}
string getName() {
return this->name;
}
int getNum() {
return this->num;
}
void print() {
cout << "Student's age = " << this->age
<< "\nStudent's name = " << this->name
<< "\nStudent's num = " << this->num << endl;
}
private:
int num;
};
int main() {
Student* student = new Student(18,"kl",1002);
student->print();
cout << "==================" << endl;
student->Person::print();
cout << "==================" << endl;
//student->print(2);
student->Person::print(2);
delete student;
return 0;
}
只要在子类中有与父类同名的函数,那么从父类继承过来的同名函数都会被隐藏,想要调用被隐藏的函数需要加上父类作用域.
3.函数覆盖_override
特点:子类中的函数与父类中的函数函数名相同、形参相同、返回值类型相同,并且子类中的函数是虚函数.
注意:虽然名字叫函数覆盖,但是父类的函数依旧是继承过来的.
三、小结
- 当子类出现与父类变量同名情况时,继承过来父类变量会被隐藏,想要访问父类变量需要加上父类的作用域.
- C++中的函数隐藏:当子类中的函数与父类函数同名时,继承过来的父类函数将被隐藏,想要访问父类函数需要加上父类的作用域.
- C++中的函数覆盖:要求子类函数是虚函数,并且与父类中的函数同名、同形参、同返回值类型.