首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >从基座下移导出分段故障

从基座下移导出分段故障
EN

Stack Overflow用户
提问于 2019-05-22 13:07:39
回答 2查看 181关注 0票数 0

我正在学习动态铸造和搜索很多网站,我得出的结论是,动态铸造可以从基础到派生到基础。但是,当我从Base转换到派生时,它会出现分段错误。这是代码:

我希望从上面的“从A”,但它给了我一个从D,即使在铸造后

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class A
{
  public:
  virtual ~A(){} 
  virtual void print()
  {
    std::cout << "from A"<<std::endl;
  }
  };
class B:  virtual public A
{
  public:
    void print()
  {
    std::cout << "from B"<<std::endl;
  }
};       
class C: virtual public A
{
  public:
    void print()
  {
    std::cout << "from C"<<std::endl;
  }
};      
class D: public B, public C
{
  public:
    void print()
  {
    std::cout << "from D"<<std::endl;
  }
};


int main(){
    A* b = new B;
    A* c = new C;
    A* d = new D;
    A* a = new A;

    B* down = dynamic_cast<B*>(a);  // this gives me problem
    down->print();

    A* up= dynamic_cast<A*>(d); // upcasten dont print from A either
    up->print();
EN

回答 2

Stack Overflow用户

发布于 2019-05-22 13:27:41

当使用dynamic_cast转换指针时,您需要检查结果指针,以确定转换在访问它之前是否有效。访问无效指针会导致未定义的行为。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    B* down = dynamic_cast<B*>(a);
    if (down == 0) {
        std::cerr << "a is not a B!\n";
    } else {
        down->print();
    }

您不需要使用dynamic_cast进行“向上转换”。允许将派生的内容分配给父级。如果不存在这种关系,您将得到一个编译时错误。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    A* up= d;
    up->print();

由于print是一个虚拟方法,所以up->print()解析为派生的实现。但是,如果希望看到基类的实现,可以显式地调用它。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    d->A::print();

在网上试试!

票数 2
EN

Stack Overflow用户

发布于 2019-05-22 13:13:58

从基础到派生和从派生到基础的转换能力不是dynamic_cast的独特特征。关键特性是dynamic_cast在运行时执行这种转换,检查大多数派生对象实际上匹配(或实际上包含)所需的目标类型。这意味着,如果转换失败,错误也是运行时错误,您的程序应该预先设置以在运行时处理此类错误。

这些错误可能是什么?dynamic_cast可能报告错误,方法是:如果在指针类型之间转换(例如X*Y* ),则返回空指针;如果在引用类型之间转换(如X&Y& ),则抛出std::bad_cast异常。

使用静态类型aA*转换为B*可以生成指向B的有效指针或null。后者正是在您的示例中发生的:a实际上指向一个类型为A的完整对象,其中没有B类型的子对象。因此,cast返回空指针,然后立即用于调用成员函数down->print()。任何取消引用空指针值的尝试都是UB (未定义的行为),这很可能表现为分段错误。

保护您的程序不受这种分段错误的影响很容易:只需检查返回的值是否为空:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
B* down = dynamic_cast<B*>(a);
if (down)
{
    // Use down all you want
}
else
{
    // Report an error, skip some actions
    // or return from the function.
    // But don't use `down`!
}

至于打印"from D",这是因为print方法被声明为虚拟的。这意味着来自大多数派生类的实现将被调用,即使您通过指向基子对象的指针调用它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56265039

复制
相关文章
shell 开始日期 结束日期循环
shell 日期循环 #!/bin/sh if [ $# == 2 ]; then datebeg=$1 dateend=$2 else echo "请输入开始时间和结束日期,格式为2017-04-04" exit 1 fi beg_s=`date -d "$datebeg" +%s` end_s=`date -d "$dateend" +%s` echo "处理时间范围:$beg_s 至 $end_s" while [ "$beg_s" -le "$end_s"
大数据工程师-公子
2019/03/14
2.8K0
当前日期得到本周的开始和结束日期
本文由来源 21aspnet,由 javajgs_com 整理编辑,其版权均为 21aspnet 所有,文章内容系作者个人观点,不代表 Java架构师必看 对观点赞同或支持。如需转载,请注明文章来源。
Java架构师必看
2021/03/22
2.8K0
js根据年月获取这月或者年的开始日期和结束日期
获取月的: //获取这个月的月初和月末 function getMonthStartEnd(vars){ var str = ''; if(vars!=null&&vars!=''){ var nyYear=vars.slice(0,4); var nyMonth=vars.slice(4,vars.length); var firstDay = new Date(nyYear,nyMonth-1); var lastDay =
tongyao
2022/06/09
5.5K0
bootstrap 日期控件起始日期&结束日期相互约束
使用bootstrap的日期控件需要单独引入bootstrap-datetimepicker.min.css和bootstrap-datetimepicker.min.js 详情及文件可以通过下面地址下载:http://www.bootcss.com/p/bootstrap-datetimepicker/index.htm
程序新视界
2022/05/06
3K0
bootstrap 日期控件起始日期&结束日期相互约束
Power Pivot智能日期运用——当前初始日期/当前结束日期
(六) 当前初始日期 1. OPENINGBALANCEMONTH/ OPENINGBALANCEQUARTER/ OPENINGBALANCEYEAR A) 语法 OpeningBalanceMonth (<expression>, <dates> [, <filter>]) OpeningBalanceQuarter (<expression>, <dates> [, <filter>]) OpeningBalanceYear (<expression>, <dates> [, <filter>] [,
逍遥之
2020/03/24
2.7K0
Power Pivot智能日期运用——当前初始日期/当前结束日期
VBA: DTPicker日期控件的使用
文章背景:最近在查看同事写的VBA代码时,发现了DTPicker日期控件。DTPicker是日期选择控件,自Win7开始,它就不是Windows系统自带的,需要下载MSCOMCT2.OCX,并在电脑上注册后才能使用。
Exploring
2022/09/20
9.5K0
VBA: DTPicker日期控件的使用
js获取上周、本周、上月、本月、上季度、本季度的开始日期、结束日期(无bug)
/** * 获取上周、本周、上月、本月、上季度、本季度的开始日期、结束日期 start * 亲测无bug。获取上月开始结束日期考虑了年份的变化 */ var now = new Date(); //当前日期 var nowDayOfWeek = now.getDay()-1; //今天本周的第几天 var nowDay = now.getDate(); //当前日 var nowMonth = now.getMonth(); //当前月 var nowYear = now.getYear(); //当
用户1065635
2019/11/27
7.1K0
shell日期循环[通俗易懂]
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/163978.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/15
5620
VBA代码库12:处理日期和时间
本文中的代码来自于www.cpearson.com,特辑录于此,方便在需要时参考。
fanjy
2021/07/12
1.8K0
时间序列 | 从开始到结束日期自增扩充数据
糖尿病是全球最常见的慢性非传染性疾病之一。流行病学调查显示,我国约11%的成年人患有糖尿病,而在住院患者中这一比例更高。
数据STUDIO
2021/06/24
3K0
pands中的日期和时间操作
其中,Date Time用于表示某个具体的时间点,Time spans用于生成时间间隔相同的时间序列;Time deltas表示时间间隔,Date offsets则表示日期间隔,这二者的作用都是用于时间运算,通过时间点+时间间隔的方式,得到新的时间点。
生信修炼手册
2020/07/16
2.1K0
SQL 中的日期和时间类型
在我们SQL中一般支持三种数据类型。 date:日历日期,包括年(四位),月和日。 time: 一天中的时间,包括小时,分和秒。可以用变量time(p)来表示秒的小数点后的数字位数(默认是0)。 通过制定 time with timezone,还可以把时区信息连同时间一起存储。 timestamp: date 和 time的组合。 可以用变量timestamp(p)来表示秒的小数点后的数字位数(这里默认值为6)。如果指定with timezone,则时区信息也会被存储 日期和时间类型的值可按如下方式说明:
Dato
2018/04/17
3.2K0
Java中的时间和日期处理
本文主要讲解Java 8的时间处理方式和Java8之前版本的时间处理方式的区别。笔者将Java8之前的jdk版本统称为旧版本。
栋先生
2018/09/29
2.7K0
Java中的时间和日期处理
js根据起始日期加间隔天数计算出结束日期
getNewDay(dateTemp, days) { dateTemp = dateTemp.split("-"); //转换为MM-DD-YYYY格式 var nDate = new Date(dateTemp[1] + "-" + dateTemp[2] + "-" + dateTemp[0]); var millSeconds = Math.abs(nDate) + days * 24 * 60 * 60 * 1000; var rDa
Wyc
2023/03/23
6.2K0
js根据起始日期加间隔天数计算出结束日期
Flutter中的日期、格式化日期、日期选择器组件在
所谓时间戳,是指自格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。
拉维
2019/08/29
26.1K0
Flutter中的日期、格式化日期、日期选择器组件在
ElasticSearch里面关于日期的存储方式
在ElasticSearch里面最常用的就是时间字段了,经常会在群里看到一些小伙伴提出有关时间的问题,为什么es查询的时间跟我实际看到的时间差8个小时呢。如果我们了解了ElasticSearch底层的时间存储方式就会比较容易的理解这个问题。 下面散仙先普及下时区的知识,想必大家也不陌生学过地理的同学都知道全球有24个时区每个时区的跨度是经度15度, 相较于两地时间表,可以显示世界各时区时间和地名的世界时区表(World Time),就显得精密与复杂多了,通常世界时区表的表盘上会标示着全球2
我是攻城师
2018/05/14
2.4K0
Java 指定日期和日期间隔,返回间隔 之前 | 之后 的日期
public class DateUtil { /** * 指定日期和日期间隔,返回间隔之前的日期 * @param specifiedDay * @param interval * @return */ public static String getSpecifiedDayAgo(String specifiedDay, int interval){ return getSpecifiedDay(specifiedDay
大数据工程师-公子
2019/03/14
2.6K0
java中的日期类
在程序的开发中我们经常会遇到日期类型的操作,Java对日期类型的操作提供了很好的支持。在最初的版本下,java.lang包中的System.currentTimeMillis();可以获取当前时间与协调时间(UTC)1970年1月1日午夜之间的时间差(以毫秒为单位测量)。我们往往通过调用该方法计算某段代码的耗时。
别团等shy哥发育
2023/02/25
3.6K0
java中的日期类
mysql—mysql中如何存储日期数据
1,特点 1)以YYYY-MM-DD HH:MM:SS[.fraction]格式存储日期时间,在mysql5.6前可以只能存储到秒,在5.6后能存储到微秒 2)datetime类型与时区无关,占用8个字节的存储空间 3)时间范围公元1000-01-01 00:00:00到9999-12-31 23:59:59,存储的时间范围非常广
全栈程序员站长
2021/04/07
5K0
Java中的时间和日期(二):java时间存储的基本原理
在java中,java.util.Date对象用于表示时间。这个对象既能表示日期,也能表示时间。原因在于这个对象内部实际上是一个long字符来存储的毫秒数。我们都知道时间通过System.currentTimeMillis()方法获取当前的系统时间戳,就能转换为我们所需要的时间:
冬天里的懒猫
2020/08/11
1.9K0

相似问题

循环生成基于开始日期和结束日期的日期列表。

11

开始日期和结束日期的Sas循环

124

基于“开始日期”和输入日期显示“结束日期”

26

基于开始日期和结束日期的JSON过滤

22

基于开始日期和结束日期的拆分记录

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文