当前位置: 首页 > news >正文

C++中如何使用子类的指针指向父类的对象

在 C++ 中,基类指针可以指向派生类对象的核心原因是 **“is-a” 关系 **(派生类是基类的一种特殊形式)。这种机制是实现多态的基础,下面从前提、语法、特性、应用及注意事项展开说明。

一、前提:public 继承

基类指针能指向派生类对象的前提是子类必须以public方式继承父类(这一点非常重要)

  • 若为privateprotected继承,派生类与基类的 “is-a” 关系被隐藏,编译器不允许基类指针指向派生类对象(隐式转换被禁止)。

二、语法:直接赋值

当满足public继承时,基类指针指向派生类对象的语法非常直接:用派生类对象的地址为基类指针赋值。

示例代码:

#include <iostream>
using namespace std;// 基类
class Base {
public:int baseNum;void baseFunc() {cout << "Base::baseFunc()" << endl;}
};// 派生类(public继承基类)
class Derived : public Base {
public:int derivedNum; // 派生类新增成员void derivedFunc() { // 派生类新增函数cout << "Derived::derivedFunc()" << endl;}
};int main() {Derived d; // 定义派生类对象Base* ptr = &d; // 基类指针指向派生类对象(合法,因public继承)return 0;
}

从主函数中,可以看出,先声明一个子类Derived的实例对象,然后再声明一个父类的指针,然后直接将子类的值,赋值给基类的指针。(这里需要注意:实例对象的变量名!=首个成员变量的地址,结构体的实例对象也是如此,变量名实例对象的变量名!=首个成员变量的地址)

三、核心特性:访问范围受限

基类指针指向派生类对象后,只能访问派生类中 “从基类继承的成员”(包括成员变量和成员函数),无法直接访问派生类新增的成员(除非强制类型转换,但不推荐)。

原因:编译器仅知道指针的类型是 “基类”,编译时会根据指针类型(而非指向对象的实际类型)检查访问权限。

示例说明:

int main() {Derived d;Base* ptr = &d;// 合法:访问从基类继承的成员ptr->baseNum = 10; ptr->baseFunc(); // 错误:无法访问派生类新增成员(编译器不知道这些成员的存在)// ptr->derivedNum = 20;  // 编译报错// ptr->derivedFunc();    // 编译报错return 0;
}

四、关键应用:结合虚函数实现多态

当基类中存在虚函数时,基类指针指向派生类对象后,调用虚函数会触发动态绑定(运行时根据对象实际类型调用对应的函数版本),这是多态的核心。

示例代码:

class Base {
public:// 基类声明虚函数virtual void vfunc() {cout << "Base::vfunc()" << endl;}
};class Derived : public Base {
public:// 派生类重写(override)虚函数void vfunc() override {cout << "Derived::vfunc()" << endl;}
};int main() {Derived d;Base* ptr = &d; // 基类指针指向派生类对象ptr->vfunc(); // 输出:Derived::vfunc()(动态绑定,调用派生类版本)return 0;
}

原理:虚函数通过 “虚函数表” 实现,基类指针指向派生类对象时,会访问派生类的虚函数表,从而调用派生类的重写版本。

五、注意事项

  1. 析构函数需设为虚函数若基类指针指向派生类对象,且通过该指针delete对象时,若基类析构函数不是虚函数,会导致派生类部分未被析构(内存泄漏)。因此需将基类析构函数声明为虚函数:

    cpp

    运行

    class Base {
    public:virtual ~Base() { cout << "Base::~Base()" << endl; } // 虚析构
    };class Derived : public Base {
    public:~Derived() override { cout << "Derived::~Derived()" << endl; }
    };int main() {Base* ptr = new Derived(); delete ptr; // 正确:先调用Derived::~Derived(),再调用Base::~Base()return 0;
    }
    
  2. 避免强制转换的风险若通过static_cast<Derived*>将基类指针强制转换为派生类指针,虽然能访问派生类新增成员,但如果指针实际指向的是基类对象,会导致未定义行为(如访问非法内存)。

总结

基类指针指向派生类对象是 C++ 多态的基础,其核心是public继承下的 “is-a” 关系。通过该机制,可统一用基类指针管理不同派生类对象,并结合虚函数实现 “同一接口,不同实现”。使用时需注意访问范围、虚析构函数等细节,避免内存问题。

http://www.dtcms.com/a/495998.html

相关文章:

  • 模版网站怎么做微信公众号微网站怎么建设
  • 推广网站多少钱足球积分排行榜最新
  • 网站建设与网页制作案例教程wordpress html5 模板下载
  • UI自动化测试实战:从入门到精通
  • android APP实现指纹免密登录的实现思路
  • AWS WAF 实战篇|如何防御爬虫、CC攻击与恶意POST请求
  • 网站开发环境有什么seo比较好的公司
  • 织梦cms怎么打不开网站phpcms做企业网站授权
  • 力扣-上升的温度
  • 从操作系统到具身智能,东土科技正加速构建自主可控产业链
  • 泉州网站建设泉州做网站建设的公司有哪些
  • 网站模板 黑白网站邮件设置方法
  • 怎么宣传自己的网站推广成都网站建设制作
  • Python爬虫第7课:多线程与异步爬虫技术
  • 厦门网站推广¥做下拉去118cr导购网站如何做免费推广
  • 基于o2o的旅游网站建设重庆网站建设索q479185700
  • 海洋专业做网站360优化大师下载安装
  • 荆州市建设厅网站微信手机网站建设
  • P13959 [ICPC 2023 Nanjing R] 计数器 题解
  • 下载 | Win11 23H2正式版最新ISO系统映像 (22631.6060、多合一版本)-修复安全漏洞
  • PCB EMI:原因、影响和缓解策略
  • 诚信档案建设网站微信小程序开发
  • 番禺哪里有做网站的公司商城网站建设实训报告模板
  • 建设网站的提成是多少编程软件scratch下载
  • C++泛型编程(函数模板以及类模板)
  • 【avalonia教程】13绑定控件
  • fastddsgen.jar 简介
  • 织梦软件网站模板下载地址佛山十大进出口贸易公司
  • 【JPEG、PNG、WebP:图像格式选择与优化实践】
  • 管理防火墙策略-firewalld、rich rule、iptables