如果您将旧的C风格的类型转换为类型A到类型B,而类型A不能转换为类型B,那么C++标准是否定义了特定的行为?反之亦然?是否定义了运行时错误的C风格转换的行为?
会有一个已知的可见行为,可以被认为是在运行时使用此非法转换的症状吗?
如果您将旧的C风格的类型转换为类型A到类型B,而类型A不能转换为类型B,那么C++标准是否定义了特定的行为?反之亦然?是否定义了运行时错误的C风格转换的行为?
会有一个已知的可见行为,可以被认为是在运行时使用此非法转换的症状吗?
四种C++风格演员中只有一种决定了演员在演出时的合法性,即dynamic_cast
。
C风格演员阵容对应于其他三个阵容的组合(static_cast
,reinterpret_cast
,const_cast
)。这些演员的有效性是在编译时确定的,或者如果在编译时无法确定,那么演员被认为是有效的。 C风格演员绝不会像dynamic_cast
那样行事。
因此,在运行时“失败”的C风格转换,即打破了有效性假设,导致未定义的行为。所以:
如果您将旧的C风格的类型转换为类型A到类型B,其中类型A不能转换为类型B,反之亦然,C++标准是否定义了特定的行为?
号
会不会有,可以认为是使用这种在运行时非法投症状已知可见的行为?
号
感谢这就是我想知道的全部 – Allahjane
[另请参见此处](http://stackoverflow.com/questions/17925124/can-i-cast-a-derived-class-to-a-private-base-class-using -c-style-cast),这个C风格转换不等同于C++风格转换的任何组合 –
编译器会赶上他们中的一些,但不是全部。这是一个灾难性的铸件的例子:
#include <iostream>
#include <string>
using namespace std;
class A {
public:
A(std::string s, int x) : m_s(s), m_x(x) {}
void print() { cout << "A::print(): str = " << m_s << ", x = " << m_x << endl; }
private:
std::string m_s;
int m_x;
};
class B {
public:
B(int x) : m_x(x) {}
void print() { m_x++; cout << "B::print(): x = " << m_x << endl; }
private:
int m_x;
};
int main(int argc, char **argv) {
A *a = new A("abc", 1);
a->print();
B *b = (B*)a;
b->print();
a->print();
return 0;
}
海合会结果(Ubuntu的5.4.0-6ubuntu1〜16.04.4)5.4.0 20160609:
A::print(): str = abc, x = 1
B::print(): x = 24828977
A::print(): str = bc, x = 1
是的,我们叫B的方法上A的数据,这意味着我们的C风格演员工作为reinterpret_cast
。 reinterpret_cast
只需要一个内存区域,并允许你对待是不同的东西。这里没有安全带。
在另一方面,如果你尝试编译这样的事情
A a;
B b;
a = (A)b;
return 0;
会造成static_cast
和编译时错误。所以C风格的转换结果取决于上下文。
这是NIGHTMARE当处理模板和auto
。
为了避免此问题,使用static_cast
(用于编译时检查)和dynamic_cast
(运行时检查)或reinterpret_cast
(用于指针和POD),写明你的意图。
实际上你的结果可能只发生在你的机器/编译器上 - 我得到一个[运行时错误](http:// ideone的.com/CsdaXh)。 b:print();'调用*未定义的行为* – UnholySheep
B :: print()修改由'std :: string'占据的sizeof(int)'字节。你可能会在那里观察到内存腐败 – ezaquarii
[reinterpret_cast']的文档(http://en.cppreference.com/w/cpp/language/reinterpret_cast)在此清楚 - 你正在调用UB。也不知道内存损坏是如何影响的,因为您的结果不能保证,并且不同的编译器会引发运行时错误。 – UnholySheep
我认为你应该提供一个例子。例如:你在谈论POD类型,类别,原始类型,指针,...? – UnholySheep
好吧,全部都是 – Allahjane
取决于实际的代码,C风格的转换可以等同于3种不同C++类型转换('static_cast','reinterpret_cast'或'const_cast')中的任何一种。这些'static_cast'会抛出编译时错误,而'reinterpret_cast'会(在大多数情况下)导致UB(如果抛出是非法的) – UnholySheep