【问题标题】:What's the difference between static_cast<type> and static_type<type *>?static_cast<type> 和 static_type<type *> 有什么区别?
【发布时间】:2021-03-03 18:31:54
【问题描述】:

到目前为止,我了解static_cast 是一个编译时操作,它以某种方式分析实体的内存并尝试将其转换为指定的对象。

我看到 static_cast 被广泛用作static_cast&lt;T *&gt;。这是什么原因?是不是因为编译器需要一个指针来检查对象的内存布局?

示例:

union U { int a; double b; } u;
void* x = &u;                        // x's value is "pointer to u"
double* y = static_cast<double*>(x); // y's value is "pointer to u.b"
char* z = static_cast<char*>(x);     // z's value is "pointer to u"

但是对于static_cast&lt;T&gt;,这会失败:

double yy = static_cast<double>(u); error: cannot convert 'union U' to 'double' without a conversion operator

我首先在类的使用中发现了这种类型的转换,并且看起来它在那里使用得更多。

Derived * d = new Derived();
Base * b = static_cast<Base *>(d);

但是同样的问题仍然存在:

Base b1 = Base();
Derived d2 = Derived();

b1 = static_cast<Base>(d2);
// No error here

能否详细说明 static_cast 在幕后的工作原理以及它与内存(即对象)的关系以及(如果需要)发生的指令?

【问题讨论】:

  • 不,static_cast 不会“分析记忆”任何东西。至于那个星号在那里的意思,那意味着一个指针。在 C++ 教科书中可以找到关于 C++ 中指针的完整和完整的讨论。在这里您可以找到您正在寻找的“详细说明”。一旦你经历了这些,这种演员阵容的原因,在这里,应该更容易理解。否则,对于 Stackoverflow 来说,这个问题太宽泛了。
  • 这能回答你的问题吗? C++ polymorphism without pointers
  • 在学习规范之前努力了解“幕后”发生了什么是倒退。除非您首先了解编译器试图产生什么行为,否则您不会理解为什么编译器会做某事。
  • 不应该怎么办?如果我理解正确的话,编译器对隐式转换的处理方式是一样的(就像我说的那样)。关于我的问题,我认为您没有意识到从初学者的角度来看,指针和“static_cast”是两个完全不同的东西。
  • 基本上,1. 多态是使用 static_cast 的典型目的,2. 多态在实际中总是使用指向多态类的指针

标签: c++ object casting


【解决方案1】:

考虑static_cast 的两种不同用例可能会有所帮助:一种用于将非指针类型相互转换,另一种用于将指针类型相互转换。

在将非指针类型相互转换时,static_cast 的含义是“进行从源值初始化目标类型的对象时会进行的那种转换”。因此,例如,在此代码中:

int aASCII = 64;
cout << static_cast<char>(aASCII) << endl; // Prints 'A'

static_cast&lt;char&gt;(aASCII) 的意思是“给我char 值,如果我要将新的char 值初始化为aASCII,我会在这里得到。”这类似于执行以下操作:

int aASCII = 64;
char temp = aASCII;
cout << temp << endl;

同样,考虑以下代码:

int total = 137;
int numItems = 42;
cout << static_cast<double>(total) / numItems << endl;

static_cast&lt;double&gt;(total) 位的意思是“在进行除法时假设totaldouble。”类似于写作

int total = 137;
int numItems = 42;
double temp = total;
cout << temp / numItems << endl;

考虑到这一点,为什么这段代码不能编译?

double yy = static_cast<double>(u); // Oops!

这有点像写作的原因

double temp = u; // Oops, doesn't compile
double yy = temp;

在这里,这不会编译,因为您无法将 double 初始化为 union 类型的变量 U

static_cast 与指针一起使用使用一组不同的规则。使用指针时,static_cast 的意思是“请假装指针指向我希望它指向的类型的对象,但前提是存在一些可行的宇宙。”因此,例如,这是完全合法的:

Base* ptr = new Derived;
Derived* dPtr = static_cast<Derived*>(ptr);

在这里,这表示“我有一个 Base* 类型的指针。有一个合理的世界,它确实指向 Derived。请将指针转换为 Derived*,但不要做任何事情运行时检查以确保这是安全的。我知道如果这实际上并不指向 Derived,那么将会发生坏事。”

但是你不能这样写:

float* ptr = new float[137];
Derived* dPtr = static_cast<Derived*>(ptr); // Error!

这是行不通的,因为 float* 类型的指针无法指向 Derived 对象(在某个时间点不对某个指针做一些非常可怕的事情)。

你的代码的原因

double* y = static_cast<double*>(x); // y's value is "pointer to u.b"

很好是因为x 是一个void*,它可以指向任何(非功能)实体,所以它可以指向double 是合理的。

【讨论】:

  • 以下操作是否相同? void* x = &amp;u; double* d = reinterpret_cast&lt;double *&gt;(&amp;u); 一样吗? double* w = static_cast&lt;double *&gt;(x); …(注意重新解释和静态)
【解决方案2】:

static_cast&lt;type&gt;static_type&lt;type *&gt; 有什么区别?

typetype* 是不同的类型。第一次转换转换为一种类型,第二次转换转换为另一种类型。

我看到 static_cast 被广泛用作static_cast&lt;T *&gt;。这是什么原因?

因为可能在这些情况下,意图是转换为 T* 类型。

【讨论】:

    猜你喜欢
    • 2015-04-15
    • 1970-01-01
    • 2015-07-17
    • 2011-02-06
    • 2017-09-14
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多