className SerialNow = *((className*)ptr);vs className & SerialNow = *((className*)ptr);



当将指针转换为对象时,使用或不使用引用有什么区别?

void someClass::method() {
xTaskCreatePinnedToCore(someTaskHandler,"SerialNowTaskTX",XT_STACK_MIN_SIZE*3,this,4,&taskHandleTX,0); // passing 'this' to task handler
}
void someTaskHandler(void *p) {
SerialNow_ SerialNow = *((SerialNow_*)p); // compile but not working properly
SerialNow_ &SerialNow = *((SerialNow_*)p); // compile and working
SerialNow_ *SerialNow = ((SerialNow_*)p); // compile and working but I prefer . over ->
int A = SerialNow.somethingA;
SerialNow.somethingB();
while(1) {

}
vTaskDelete(NULL);
}

备注

首先,请记住,在c++中强制转换void*指针是一件相当危险的事情,如果指向的对象与您要强制转换的类型不兼容,则可能是UB。

与其在括号之间进行类似C的强制转换,不如使用c++的更显式强制转换,这样可以更好地显示危险级别。如果p是多态碱基类型,建议使用更安全的dynamic_cast。否则,请使用static_cast,以避免一些常见错误。只有在最后关头才使用reinterpret_cast,但是你必须非常确定你在做什么。

你们的陈述有什么不同?

如果我们假设p是一个有效的指针,指向与SerialNow_兼容的类型,这就是你的不同语句的含义:

SerialNow_ SerialNow = *((SerialNow_*)p); 

第一个对p所指向的对象进行复制。如果稍后更改b所指向的对象的内容,则不会对对象SerialNow产生影响。请记住,如果p所指向的对象不是SerialNow_,而是一个子类,则可能发生切片。

SerialNow_ &SerialNow = *((SerialNow_*)p);

第二个参数创建了一个引用,该引用指向p所指向的对象。您可以将SerialNow当作对象来使用,但实际上它指向的对象与p所指向的对象是同一个对象:

SerialNow_ *SerialNow = ((SerialNow_*)p);

第三个语句创建一个指向p所指向的对象的指针:

第二和第三方面的多态性。如果p所指向的对象不是SerialNow_,而是一个子类型,则多态性将工作,即如果调用虚函数,将调用与该对象的实际运行时类型相对应的对象。

Case 1

这里我们考虑语句:

SerialNow_ SerialNow = *((SerialNow_*)p);

这里void*p被强制转换(使用显式类型转换)为SerialNow_*。接下来,生成的SerialNow_*解引用的使用*operator生成SerialNow_类型的对象。

最后,生成的SerialNow_对象被用作初始化式初始化左侧名为SerialNow的对象。新初始化的对象SerialNow是原始对象的副本。这意味着如果你改变了SerialNow,它不会影响p所指向的原始对象。

案例2

这里我们考虑语句:

SerialNow_ &SerialNow = *((SerialNow_*)p); 
在这种情况下,除了SerialNow别名之外,大部分过程与情况1相同。对于结果对象。这与情形一的唯一不同之处在于,在情形1中,左侧的对象SerialNow是原始对象的副本,而这里左侧的SerialNow是对原始对象的左值引用。这意味着如果你改变了SerialNow,它将影响p指向的原始对象。

情况3

这里我们考虑语句:

SerialNow_ *SerialNow = ((SerialNow_*)p);

这里void*p被强制转换为SerialNow_*。但是结果指针是未被解引用的不像情形1和情形2。因此,这里左侧名为SerialNow的对象是通过显式类型转换产生的指针初始化的。

而且,SerialNow是由显式类型转换产生的指针的副本。

相关内容

  • 没有找到相关文章

最新更新