1、知识图谱
2、举例
例1:using改变派生类中继承的基类成员权限
#include<iostream>
using namespace std;
//基类People
class People {
public:
void show();
protected:
char *m_name;
int m_age;
};
void People::show() {
cout << m_name << "的年龄是" << m_age << endl;
}
//派生类Student
class Student : public People {
public:
void learning();
public:
using People::m_name; //将protected改为public
using People::m_age; //将protected改为public
float m_score;
private:
using People::show; //将public改为private
};
void Student::learning() {
cout << "我是" << m_name << ",今年" << m_age << "岁,这次考了" << m_score << "分!" << endl;
}
int main() {
Student stu;
stu.m_name = "小明";
stu.m_age = 16;
stu.m_score = 99.5f;
stu.show(); //compile error
stu.learning();
return 0;
}
例2:由内而外的按照函数名进行查找
#include<iostream>
using namespace std;
//基类Base
class Base{
public:
void func();
void func(int);
};
void Base::func(){
cout<<"Base::func()"<<endl; }
void Base::func(int a){
cout<<"Base::func(int)"<<endl; }
//派生类Derived
class Derived: public Base{
public:
void func(char *);
void func(bool);
};
void Derived::func(char *str){
cout<<"Derived::func(char *)"<<endl; }
void Derived::func(bool is){
cout<<"Derived::func(bool)"<<endl; }
int main(){
Derived d;
d.func("c.biancheng.net");
d.func(true);
d.func(); //compile error
d.func(10); //compile error
d.Base::func();
d.Base::func(100);
return 0;
}
虽然 Derived 类和 Base 类都有同名的 func 函数,但它们位于不同的作用域,Derived 类的 func 会遮蔽 Base 类的 func。d 是 Derived 类的对象,调用 func 函数时,编译器会先在 Derived 类中查找“func”这个名字,发现有两个,也即void func(char*)和void func(bool),这就是一组候选函数。
执行到第 26、27 行代码时,在候选函数中没有找到匹配的函数,所以调用失败,这时编译器会抛出错误信息,而不是再到 Base 类中查找同名函数。
例3:继承时的对象内存模型
以下是基类的内存占用情况:
以下是派生类的内存占用模型:
当继承过程中发生遮蔽时,派生类的内存占用情况如下:
例4:在派生类构造函数中调用基类的构造函数完成基类成员变量的初始化
Student::Student(char *name, int age, float score): People(name, age), m_score(score){
}
在上面的例子中,People是基类,Student类中对构造函数采用列表的方式进行初始化,调用了基类的构造函数。
注意下面的例子是错误的,因为构造函数不可以直接调用:
Student::