C++ static_cast相同父类的子类之间强制转换(子类A的指针转换成子类B)(Ray Tracing the next week 中BVH部分遇到的问题)

万恶之源:

hittable_list world = static_cast<hittable_list>(make_shared<bvh_node>(world, 0, 1));

本文只讨论手段是否能通过编译,是否应该这样做、有无必要这样做 不是讨论的重点

1、static_cast能够实现父类指针和子类指针相互转换

这是众所周知的吧,不知道的可以百度一下static_cast的用法

class A {};
class B : public A {};

void test01()
{
	//这样转换是OK的 父类指针 转 子类指针
	A* ptrA = new A();
	B* ptrB = static_cast<B*>(ptrA);
}

void test02()
{
	//这样转换也是OK的 子类指针强转为父类指针
	B* ptrA = new B();
	A* ptrB = static_cast<A*>(ptrA);
}

int main()
{
	// test01();
	test02();
	
	cin.get();
	return 0;
}

2、尝试把子类A的指针转到子类B (失败)

下面这串代码,hittable_listbvh_node具有相同父类hittable

hittable_list world = static_cast<hittable_list>(make_shared<bvh_node>(world, 0, 1));

测试1:首先搞个空的基类,俩儿子也是空的

  • test01():SonA* 转换成 SonB —— error
  • test02():SonA* 转换成 SonB* —— error
  • test03(): SonA* 转成 Base* 再转 SonB*
#include <iostream>
using namespace std;

class Base {};
class SonA : public Base {};
class SonB : public Base {};

void test01()
{
	SonA* ptrA = new SonA();
	SonB B;
	B = static_cast<SonB>(ptrA);
}

void test02()
{
	SonA* ptrA = new SonA();
	SonB* ptrB = static_cast<SonB*>(ptrA);
}
void test03()
{
	SonA* ptrA = new SonA();
	Base* ptr = static_cast<Base*>(ptrA);
	SonB* ptrB = static_cast<SonB*>(ptr);
}

int main()
{
	//test01(); //错误	C2440	“static_cast”: 无法从“SonA *”转换为“SonB”
	//test02(); //错误	C2440	“static_cast”: 无法从“SonA *”转换为“SonB *”
	test03();	//可以

	cin.get();
	return 0;
}

3、把子类A的指针转到子类B (成功)

Key idea :隐式类型转换
c++中,隐式类型转换允许我们做出这样的操作

#include <string>
#include <iostream>
using namespace std;

class Base
{
public:
	Base() {}
	Base(string str)   // 注意这个构造函数需要的你传入的是string类的对象
	{
		cout << str << endl;
	}
};
int main()
{
	const char* c = "hello"; 
	Base base1(c); // 发生隐式转换:编译器认为const char* 可以转换成 string类型
	
	cin.get();
	return 0;
}

利用隐式转换的思想,我们可以这样操作

  • 给B一个有参构造,形参接收一个为 Base* 指针变量
  • 此时如果我们传入一个SonA* 类型的指针变量,则会发生隐式转换,
  • B因为有这个构造函数,就可以构造出一个B类型对象
#include <iostream>
using namespace std;

class Base {};
class SonA : public Base {};

class SonB : public Base 
{
public:
	SonB(){}
	SonB(Base* base){}	
};

int main()
{
	SonA* ptrA = new SonA();
	SonB b = static_cast<SonB>(ptrA);
	cin.get();
	return 0;
}

可以看到,代码中,hittable_list类里,确实刚好有个构造函数,符合上述情况

hittable_list world = static_cast<hittable_list>(make_shared<bvh_node>(world, 0, 1));

在这里插入图片描述

写给自己看,这行代码执行后,不光是转换了,还把bvh树给压到objects中了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宗浩多捞

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值