首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >className SerialNow = *(( className *)ptr);vs className &SerialNow =*(className*)ptr;

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

Stack Overflow用户
提问于 2022-05-22 13:52:18
回答 2查看 53关注 0票数 1

当将指针投射到对象时,使用或不引用有什么区别?

代码语言:javascript
复制
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);
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-05-22 14:53:01

初步评论

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

与括号之间的C类强制转换不同,更倾向于使用C++更显式的强制转换,这更好地显示了危险的程度。如果p是多态基类型,则更喜欢使用更安全的dynamic_cast。否则,使用static_cast可以避免一些常见的错误。只有在最后才能使用reinterpret_cast,但您必须真正确定自己在做什么。

你的陈述有什么区别?

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

代码语言:javascript
复制
SerialNow_ SerialNow = *((SerialNow_*)p); 

第一个是p指向的对象的副本,如果您稍后更改b指向的对象的内容,它将不会对对象SerialNow产生影响。请记住,如果p所指向的对象不是SerialNow_而是子类,则可能会出现切片

代码语言:javascript
复制
SerialNow_ &SerialNow = *((SerialNow_*)p);

第二种方法创建一个引用,该引用引用p指向的对象。您可以像使用对象一样使用SerialNow,但实际上它引用的对象与p指向的对象相同:

代码语言:javascript
复制
SerialNow_ *SerialNow = ((SerialNow_*)p);

第三种方法创建指向由p指向的对象的指针:

第二和第三方面的多态性。如果p所指向的对象不是一个SerialNow_,而是一个子类型,那么多态就可以工作,也就是说,如果您调用一个虚拟函数,那么对应于对象的实际运行时类型的那个将被调用。

票数 1
EN

Stack Overflow用户

发布于 2022-05-22 14:51:26

案例1

在此,我们审议以下声明:

代码语言:javascript
复制
SerialNow_ SerialNow = *((SerialNow_*)p);

在这里,void* p被转换为SerialNow_* (使用显式类型转换)。接下来,生成的SerialNow_*是使用取消引用的,使用*operator生成一个SerialNow_类型的对象。

最后,生成的SerialNow_对象被用作初始化器,用于初始化左侧名为SerialNow的对象。新初始化的对象SerialNow是原始对象的副本。这意味着,如果您对SerialNow进行更改,它将不会影响p所指向的原始对象。

案例2

在此,我们审议以下声明:

代码语言:javascript
复制
SerialNow_ &SerialNow = *((SerialNow_*)p); 

在本例中,大多数进程与案例1相同,但这次SerialNow是结果对象的别名。这与案例1不同,只有在案例1中,左侧的对象SerialNow是原始对象的副本,而左边的SerialNow是对原始对象的lvalue引用。这意味着,如果您对SerialNow进行更改,它将影响p所指向的原始对象。

案例3

在此,我们审议以下声明:

代码语言:javascript
复制
SerialNow_ *SerialNow = ((SerialNow_*)p);

在这里,void* p被抛给了SerialNow_*。但结果指针是,与案例1和案例2不同,没有取消引用的。因此,在这里,左手边的名为SerialNow的对象是由显式类型转换产生的指针初始化的。

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

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

https://stackoverflow.com/questions/72338190

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档