浅谈C++ 基类指针和子类指针的相互赋值

发布时间 - 2026-01-10 22:00:36    点击率:

首先,给出基类animal和子类fish

//============================================================== 
//      animal.h 
// 
// author : zwq 
// describe: 非虚函数情况下,将子类指针赋给积累指针,验证最终调用 
//      基类函数还是子类函数。 
//============================================================== 
#ifndef ANIMAL_H 
#define ANIMAL_H 
 
//=============================================================== 
// 
//        animal 
//        动物基类 
// 
//=============================================================== 
class animal 
{ 
public: 
  void breathe();   // 非虚函数 
}; 
 
//=============================================================== 
// 
//           animal 
//        鱼类,集成于动物基类 
// 
//=============================================================== 
class fish : public animal 
{ 
public: 
  void breathe();   // 非虚函数 
}; 
 
#endif 
#include "StdAfx.h" 
#include <iostream> 
#include "Animal.h" 
 
using namespace std; 
 
//=============================================================== 
// 
//        animal 
//        动物基类 
// 
//=============================================================== 
 
void animal::breathe() 
{ 
  cout << "animal breathe" << endl; 
} 
 
//=============================================================== 
// 
//           animal 
//        鱼类,集成于动物基类 
// 
//=============================================================== 
 
void fish::breathe() 
{ 
  cout << "fish bubble" << endl; 
} 

一.基类指针和子类指针之间相互赋值

(1)将子类指针赋值给基类指针时,不需要进行强制类型转换,C++编译器将自动进行类型转换。因为子类对象也是一个基类对象。

(2)将基类指针赋值给子类指针时,需要进行强制类型转换,C++编译器将不自动进行类型转换。因为基类对象不是一个子类对象。子类对象的自增部分是基类不具有的。

执行以下代码,看看会报什么错误:

编译时,报如下错误信息:

--------------------Configuration: CPlusPlusPrimer - Win32 Debug--------------------
Compiling... CPlusPlusPrimer.cpp E:\Study\example\CPlusPlusPrimer\CPlusPlusPrimer.cpp(94) : error C2440: '=' : cannot convert from 'class animal *' to 'class fish *'        
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast Error executing cl.exe.

CPlusPlusPrimer.exe - 1 error(s), 0 warning(s)

根据以上错题提示信息,对代码做如下修改:

void ExamAnimal() 
{ 
  // 将子类指针直接赋给基类指针,不需要强制转换,C++编译器自动进行类型转换 
  // 因为fish对象也是一个animal对象 
  animal* pAn; 
  fish* pfh = new fish; 
  pAn = pfh; 
   
  delete pfh; 
  pfh = NULL; 
   
  // 将基类指针直接赋给子类指针,需要强制转换,C++编译器不会自动进行类型转换 
  // 因为animal对象不是一个fish对象 
  fish* fh1; 
  animal* an1 = new animal; 
  // 修改处: 
  // 进行强制类型转化 
  fh1 = (fish*)an1; 
 
  delete an1; 
  an1 = NULL; 
} 

再次编译,通过。

二.子类指针赋给基类指针时内存分析

(1)int变量赋给char变量

整型int转换为char类型时,只有一个字节的内容能够放进char类型,剩下的三个字节内容放不下,被截掉,丢失精度。 两个变量或者对象进行转换时,一定要看两者的内存模型是否互相匹配。

(2)子类fish指针赋给基类animal指针

下面看看子类fish指针赋给基类animal指针时,内存的变化: 当我们构造fish类的对象时,首先要调用animal类的构造函数去构造animal类的构造函数,然后才调用fish类的构造函数完成自身部分的构造,从而拼接出一个完整的fish对象。当我们将fish类对象转换为animal类对象时,该对象就被认为是原对象整个内存模型的上半部分,也就是图中animal对象的内存部分。当我们利用类型转换后的对象指针去调用它的方法时,自然是调用它所在的内存中的方法。 在这里,animal类对象类似于char类型的对象,fish类对象类似于int类型的对象,将fish类对象赋给animal类对象时,会截取fish类对象自身的部分,剩下fish类对象中的animal部分。

(3)基类animal指针赋给子类fish指针

基类animal对象包含的信息少,类fish对象包含的信息多,将信息少的对象直接转换为信息多的对象时(没有强制类型转换),显然是无法构造出多出的信息。在编译时,也会发生如下错误:error C2440: '=' : cannot convert from 'class animal *' to 'class fish *'。 这时,需要做强制类型转换:

// 将基类指针直接赋给子类指针,需要强制转换,C++编译器不会自动进行类型转换 
// 因为animal对象不是一个fish对象 
fish* fh1; 
animal* an1 = new animal; 
// 进行强制类型转化 
fh1 = (fish*)an1; 

以上就是小编为大家带来的浅谈C++ 基类指针和子类指针的相互赋值全部内容了,希望大家多多支持~


# 基类指针和子类指针赋值  # C++获取类的成员函数的函数指针详解及实例代码  # C/C++静态类和this指针详解及实例代码  # C++ 基类指针和子类指针相互赋值的实现方法  # 实例解析C++中类的成员函数指针  # C++中指针的数据类型和运算相关知识小结  # C++指向类成员函数的指针详细解析  # C++带有指针成员的类处理方式详解  # 子类  # 当我们  # 转换为  # 不需要  # 会报  # 类似于  # 在这里  # 也会  # 提示信息  # 只有一个  # 将不  # 浅谈  # 错误信息  # 多出  # 小编  # 图中  # 放不下  # 大家多多  # 一定要看  # 象中 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】  如何在Tomcat中配置并部署网站项目?  javascript基本数据类型及类型检测常用方法小结  js实现获取鼠标当前的位置  如何在阿里云通过域名搭建网站?  如何快速搭建FTP站点实现文件共享?  微信公众帐号开发教程之图文消息全攻略  Laravel怎么上传文件_Laravel图片上传及存储配置  如何在宝塔面板中修改默认建站目录?  laravel怎么配置Redis作为缓存驱动_laravel Redis缓存配置教程  微信小程序 HTTPS报错整理常见问题及解决方案  浏览器如何快速切换搜索引擎_在地址栏使用不同搜索引擎【搜索】  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  英语简历制作免费网站推荐,如何将简历翻译成英文?  Python自动化办公教程_ExcelWordPDF批量处理案例  Laravel如何安装使用Debugbar工具栏_Laravel性能调试与SQL监控插件【步骤】  香港服务器网站卡顿?如何解决网络延迟与负载问题?  如何在宝塔面板中创建新站点?  edge浏览器无法安装扩展 edge浏览器插件安装失败【解决方法】  Python自然语言搜索引擎项目教程_倒排索引查询优化案例  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  香港服务器租用费用高吗?如何避免常见误区?  如何构建满足综合性能需求的优质建站方案?  如何选择可靠的免备案建站服务器?  如何用PHP快速搭建高效网站?分步指南  如何在阿里云ECS服务器部署织梦CMS网站?  如何快速上传自定义模板至建站之星?  打造顶配客厅影院,这份100寸电视推荐名单请查收  php静态变量怎么调试_php静态变量作用域调试技巧【解答】  如何使用 Go 正则表达式精准提取括号内首个纯字母标识符(忽略数字与嵌套)  详解Oracle修改字段类型方法总结  如何快速上传建站程序避免常见错误?  如何快速建站并高效导出源代码?  linux top下的 minerd 木马清除方法  免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?  如何在景安服务器上快速搭建个人网站?  JavaScript常见的五种数组去重的方式  活动邀请函制作网站有哪些,活动邀请函文案?  如何在景安云服务器上绑定域名并配置虚拟主机?  Win11怎么关闭透明效果_Windows11辅助功能视觉效果设置  如何续费美橙建站之星域名及服务?  Laravel如何操作JSON类型的数据库字段?(Eloquent示例)  如何基于云服务器快速搭建网站及云盘系统?  如何在香港免费服务器上快速搭建网站?  大型企业网站制作流程,做网站需要注册公司吗?  利用vue写todolist单页应用  Laravel如何实现图片防盗链功能_Laravel中间件验证Referer来源请求【方案】  如何用已有域名快速搭建网站?  Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程  Laravel队列由Redis驱动怎么配置_Laravel Redis队列使用教程