为什么只有 static_cast 能够 return 请求类型的新对象?
Why is only static_cast able to return new object of requested type?
在static_cast、dynamic_cast、reinterpret_cast和const_cast中,只有static_cast能够return一个理想类型的对象,而另一种类型只能 return 指针或对表示的引用。为什么会这样?
示例:
int y = 3;
double z = reinterpret_cast<double> (y);//error
double z = reinterpret_cast<double&> (y);//ok
double z = static_cast<double> (y);//but this is ok!!!
const int y = 3;
int z = const_cast<int> (y);//error
int z = const_cast<int&> (y);//ok
和 dynamic_cast:
using namespace std;
class Gun
{
public:
virtual void shoot(){
cout << "BANG!\n";
}
};
class MachineGun : public Gun{
public:
void shoot() override{
cout <<"3X-BANG\n";
}
};
int main()
{
Gun gun;
MachineGun tt;
Gun* gunp = &gun;
Gun* gunp1 = &tt;
Gun* newGun = dynamic_cast<Gun*>(gunp1);//ok
Gun newGun1 = dynamic_cast<Gun>(tt);//error
}
Only static_cast is able to return an object of desirable type
这是不正确的。当转换目标是对象类型时,所有转换 return 一个对象。
也就是说:
- const_cast 目标只能是一个引用,指向对象的指针或指向成员的指针。这是因为其他类型不是复合类型,其“内部”类型的 cv 限定符可以修改。
- dynamic_cast 目标只能是对象的引用或指针。没有间接就不能拥有多态性。引用和指针是 C++ 中存在的间接形式。
我正在尝试根据示例进行解释,作为对确实解释演员表性质的其他答案的补充。
int y = 3;
double z = reinterpret_cast<double> (y);//error
这不是 11 种允许的转换之一,reinterpret_cast
. Also std::bit_cast
不能在大多数平台上转换它,因为 int
通常没有足够的位用于 double
。所以不确定你想要实现什么。
double z = reinterpret_cast<double&> (y);//ok
这出现在有效列表 reinterpret_cast
中,但可能会导致未定义的行为,原因与 std::bit_cast
拒绝的原因相同。在典型的实现中,您的 z
比 y
大,因此占用的位超出了 y
的内存位置。在这些地方更喜欢 std::bit_cast
不会编译为未定义行为但拒绝编译。
double z = static_cast<double> (y);//but this is ok!!!
但这是完全正确的。它实际上与
相同
double z = y;
编译器甚至不会对后者发出警告。但是,当 y
的值范围不完全适合 z
时,则不清楚是否是故意的。在这种情况下,最好使用 former 来表示意图。
const int y = 3;
int z = const_cast<int> (y);//error
很好。荒唐const_cast
编译不通过!或者您尝试实现的效果与更具可读性的效果有何不同
int z = y;
我会写的。请描述你会写前者的情况。
int z = const_cast<int&> (y);//ok
有效,但与以前一样不需要且令人困惑。我只会在这种情况下使用 const_cast
:
int x;
const int& y = x;
int& z = const_cast<int&> (y);
z = 42;
这里我知道引用 const y
的东西本来就不是 const ,所以将它修改为 42
不是未定义的行为。
关于dynamic_cast
你的例子根本没有意义:
Gun newGun1 = dynamic_cast<Gun>(tt);//error
它可能正在尝试做类似的事情:
Gun newGun1 = tt;
即编译。然而,newGun1
的结果是用 MachineGun tt
的切片 Gun
基础子对象初始化的,这通常是编程错误。但是,您尝试通过演员表实现的目标仍然是完全黑暗的。
也许一个简短(令人难忘)的答案是 static_cast
可以采用没有引用(也没有指针)的类型,因为它是唯一可以调用目标类型的构造函数的类型转换。
如有错误请指正
在static_cast、dynamic_cast、reinterpret_cast和const_cast中,只有static_cast能够return一个理想类型的对象,而另一种类型只能 return 指针或对表示的引用。为什么会这样?
示例:
int y = 3;
double z = reinterpret_cast<double> (y);//error
double z = reinterpret_cast<double&> (y);//ok
double z = static_cast<double> (y);//but this is ok!!!
const int y = 3;
int z = const_cast<int> (y);//error
int z = const_cast<int&> (y);//ok
和 dynamic_cast:
using namespace std;
class Gun
{
public:
virtual void shoot(){
cout << "BANG!\n";
}
};
class MachineGun : public Gun{
public:
void shoot() override{
cout <<"3X-BANG\n";
}
};
int main()
{
Gun gun;
MachineGun tt;
Gun* gunp = &gun;
Gun* gunp1 = &tt;
Gun* newGun = dynamic_cast<Gun*>(gunp1);//ok
Gun newGun1 = dynamic_cast<Gun>(tt);//error
}
Only static_cast is able to return an object of desirable type
这是不正确的。当转换目标是对象类型时,所有转换 return 一个对象。
也就是说:
- const_cast 目标只能是一个引用,指向对象的指针或指向成员的指针。这是因为其他类型不是复合类型,其“内部”类型的 cv 限定符可以修改。
- dynamic_cast 目标只能是对象的引用或指针。没有间接就不能拥有多态性。引用和指针是 C++ 中存在的间接形式。
我正在尝试根据示例进行解释,作为对确实解释演员表性质的其他答案的补充。
int y = 3;
double z = reinterpret_cast<double> (y);//error
这不是 11 种允许的转换之一,reinterpret_cast
. Also std::bit_cast
不能在大多数平台上转换它,因为 int
通常没有足够的位用于 double
。所以不确定你想要实现什么。
double z = reinterpret_cast<double&> (y);//ok
这出现在有效列表 reinterpret_cast
中,但可能会导致未定义的行为,原因与 std::bit_cast
拒绝的原因相同。在典型的实现中,您的 z
比 y
大,因此占用的位超出了 y
的内存位置。在这些地方更喜欢 std::bit_cast
不会编译为未定义行为但拒绝编译。
double z = static_cast<double> (y);//but this is ok!!!
但这是完全正确的。它实际上与
相同double z = y;
编译器甚至不会对后者发出警告。但是,当 y
的值范围不完全适合 z
时,则不清楚是否是故意的。在这种情况下,最好使用 former 来表示意图。
const int y = 3;
int z = const_cast<int> (y);//error
很好。荒唐const_cast
编译不通过!或者您尝试实现的效果与更具可读性的效果有何不同
int z = y;
我会写的。请描述你会写前者的情况。
int z = const_cast<int&> (y);//ok
有效,但与以前一样不需要且令人困惑。我只会在这种情况下使用 const_cast
:
int x;
const int& y = x;
int& z = const_cast<int&> (y);
z = 42;
这里我知道引用 const y
的东西本来就不是 const ,所以将它修改为 42
不是未定义的行为。
关于dynamic_cast
你的例子根本没有意义:
Gun newGun1 = dynamic_cast<Gun>(tt);//error
它可能正在尝试做类似的事情:
Gun newGun1 = tt;
即编译。然而,newGun1
的结果是用 MachineGun tt
的切片 Gun
基础子对象初始化的,这通常是编程错误。但是,您尝试通过演员表实现的目标仍然是完全黑暗的。
也许一个简短(令人难忘)的答案是 static_cast
可以采用没有引用(也没有指针)的类型,因为它是唯一可以调用目标类型的构造函数的类型转换。
如有错误请指正