ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基类与派生类的关系(C++)

2026/9/23 13:21:00 拓冰建站 浏览量
基类与派生类的关系(C++)

    • 3.2 基类与派生类的关系
      • 3.2.1 向上造型和向下造型
      • 3.2.2 成员函数的重定义(名字隐藏)

3.2 基类与派生类的关系

3.2.1 向上造型和向下造型

子类对象会继承基类的属性的行为,任何时候子类对象都可以被当做基类类型的对象,通过子类对象可以直接访问基类中的成员,如同是基类对象在访问它们一样

**向上造型(upcast):**将子类类型的指针或引用转换为基类类型的指针或引用;这种操作性缩小的类型转换,在编译器看来是安全的,可以隐式转换。

**向下造型(downcast):**将基类类型的指针或引用转换为子类类型的指针或引用;这种操作性放大的类型转换,在编译器看来是危险的,不能隐式转换,但是可以显式转换。

#include <iostream>
using namespace std;class Human{
private:int m_private;
protected:string m_name;int m_age;
public:Human(const string& name, int age){m_name = name;m_age = age;}void eat(const string& food){cout << "今天吃:" << food << endl;}void sleep(int hour){cout << "今天睡了: " << hour << "小时" << endl;}
};class Student : public Human{
private:int m_no;
public:Student(const string& name, int age, int no):Human(name, age), m_no(no){// Human(name,age);//error}void who() {cout << "我是:" << m_name << " 今年: " << m_age << " 学号:" << m_no << endl;}void learn(const string& course){cout << "我正在学习:" << course << endl;}
};class Teacher : public Human{
private:int m_salary;
public:Teacher(const string& name, int age, int salary):Human(name, age), m_salary(salary){}void who(){cout << "我是:" << m_name << " 今年:" << m_age << " 工资是: " << m_salary << endl;}void teach(const string& course) {cout << "我正在讲: " << course << endl;}
};
int main(void) {Human hu("王铁蛋", 18);hu.eat("炸鸡柳");hu.sleep(18);Student st("刘钢蛋", 19, 10002);st.who();st.eat("汉堡包");st.sleep(19);st.learn("C++编程");Teacher te("王翠花", 32, 15000);te.who();te.teach("C++");// Student * --------->  Human * : 向下造型Human *ph = &st; ph->eat("汉堡包");ph->sleep(19);//ph->who(); //error  Human基类中没有who()函数 // Human * -----------> Student * : 向上造型 (合理)//Student *s1 = &hu;//errorStudent *s1 = static_cast<Student *>(ph); s1->who();Human h("赵四", 39);// Human * --------> Student * : 向上造型(不合理)Student *s2 = static_cast<Student *>(&h);s2->who();// 扩大访问范围了  输出的结果不确定return 0;
}

3.2.2 成员函数的重定义(名字隐藏)

重定义:简单的说就是子类中定义了和父类的同名函数,对父类的成员函数造成了隐藏(多态时会进一步限定)

#include <iostream>
using namespace std;class Base{
private:int m_x;
public:void set(int x) {m_x = x;}void print(){cout << "Base class: " << "m_x = " << m_x << endl;}
};class Derived: public Base {
private:int m_y, m_z;
public:void set(int y, int z) {m_y = y;m_z = z;}void print(){cout << "Derived class: " << "m_y = " << m_y << "m_z = " << m_z << endl;}
};int main(void) {Derived d;d.Base::set(10);d.set(10,20);	//这个地方默认是 派生类中的成员函数d.Base::print();//想要搞清楚调用基类还是派生类中的成员函数 加作用域限定符d.print();return 0;
}