基类与派生类的关系(C++)
2023-12-29 22:36:54
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;//error
Student *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;
}
文章来源:https://blog.csdn.net/qq_36091214/article/details/135298712
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!