【发布时间】:2021-04-30 15:58:48
【问题描述】:
考虑以下程序:
#include <iostream>
class Pet {};
class Cat: public Pet {
public:
void meow() const {
std::cout << "Meow!" << std::endl;
}
};
int main() {
Cat myCat;
Pet& myPet = myCat;
static_cast<Cat&>(myPet).meow();
// Undefined behavior?
Pet myOtherPet;
static_cast<Cat&>(myOtherPet).meow();
}
在我的机器上,输出是:
Meow!
Meow!
正如预期的那样,myPet 能够很好地meow(),因为它不只是任何Pet&,而是分配了值myCat,它属于Cat。
然而,令我惊讶的是myOtherPet 也可以meow()。我可以推测,由于meow() 不使用任何类数据,该程序只是让我将我的通用宠物用作猫。
更糟糕的是,请考虑以下程序:
#include <iostream>
class Person {};
class Student: public Person {
public:
float Average = 28.7;
void print() const {
std::cout << "Average: " << Average << std::endl;
}
};
int main() {
Person& myPerson = myStudent;
static_cast<Student&>(myPerson).print();
// Undefined behavior?
Person myOtherPerson = myStudent;
static_cast<Student&>(myOtherPerson).print();
}
在我的机器上,输出是:
Average: 28.7
Average: 0
这一次myOtherPerson,不是学生,只是神奇的得到了Average的数据。
- 这种行为在编译器之间是一致的还是未定义的?
- 这样的使用会导致分段错误吗?
【问题讨论】:
-
什么是“非参考”?
-
您是从左值进行转换,因此将转换后的对象视为引用。
-
"myOtherPerson,不是学生,刚刚神奇地获得了附加到它的平均数据" - 不,它没有。
print调用调用未定义的行为,并且打印出像0这样的垃圾值是这种 UB 的一种可能表现形式。
标签: c++ static-cast