关于c++中的static_cast

static cast - About static_cast in c++

本文关键字:cast static 中的 c++ 关于      更新时间:2023-10-16

我正在阅读http://www.gotw.ca/gotw/036.htm(它是关于直接初始化和复制初始化),它有一个类似的提及:

static_cast<S>(t); // performing a static_cast

static_cast使用直接初始化。

谁能解释为什么static_cast需要使用初始化?我认为cast只是重新解释给定内存位置中的位…

reinterpret_cast重新解释位。static_cast是一种感知语义的转换。它将尝试找到一个合理的操作,将值从一种类型转换为另一种类型,如果不能,则编译失败。

合理的操作是各种整数和浮点类型之间的转换(可能带有截断),自动转换为bool,将bool转换为数字等。此外,还使用用户定义的转换操作符和单参数构造函数从用户定义类型转换到用户定义类型。在使用构造函数的情况下,它使用直接初始化,因此可以使用显式构造函数,而不像隐式转换那样不能。

static_cast在类层次结构中执行查找,以便转换到正确的类,它不会重新解释位(即reinterpret_cast)。

dynamic_cast也是如此,区别在于static_cast是在编译时进行的,而dynamic_cast是在运行时进行的。

看下面的例子:A: B, A: C, D: B,C

下面的代码将输出指针指向不同的内存块

{
  D *ptrToD = new D();
  C *ptr1 = static_cast<C>(ptrToD);
  C *ptr2 = reinterpret_cast<C>(ptrToD);
  if (ptr1==ptr2)
  {
     printf("Pointers point to the same memory block");
  } else
  {
     printf("Pointers point to different memory blocks");
  }
}

如果你看一下内存,它看起来像ABACD

如果你想将它强制转换为C, C从D开始的地方开始+sizeof(B) (AC),而A和B从与D相同的内存块开始

也许这不是一个完全解释性的例子,但是看下面的

void f(double **arg) {} // just to make a point
int main() {
    double d(1.);
    double *pd = &d;
    double const *cpd = &d;
    f(&pd); // OK 
    f(&(const_cast<double*>(cpd))); // Error
}

发出的错误是

error C2102: &需要l值

static_cast的行为与此相同,因为它们返回一个必须绑定到变量的r值。它就是被初始化的变量

我认为类型转换只是重新解释给定内存位置中的位…

不,强制类型转换执行类型转换。在这种情况下,它将t转换为S类型;这种转换是可能的,因为T继承自S,所以可以通过复制t的这一部分来生成新的S。像这样复制基本子对象有时被称为切片

谁能解释为什么static_cast需要使用初始化?

类型转换需要创建新类型的(临时)对象;该对象需要初始化,static_cast的规则指定它使用直接初始化。由于S是一个类类型,这意味着它是通过调用合适的构造函数来初始化的——在本例中,是隐式声明的复制构造函数,它通过复制tS子对象来初始化对象。