[c++11 characteristics]—static_cast, dynamic_cast, const_cast, reinterpret_cast analysis

Table of contents

1.static_cast

2.dynamic_cast

Why can dynamic_cast only be used for classes with virtual functions?

3.const_cast

4.reinterpret_cast

The role of reinterpret_cast

What is the difference between static_cast and dynamic_cast?


1.static_cast

概念

static_cast It is a type conversion operator in C++ , used to perform compile-time type conversion. It is usually used to perform type conversion at compile time without checking at run time.

static_castCan be used for the following common type conversions:

1. Conversion of basic data types :

static_castCan be used to perform conversions between basic data types, such as converting an integer to a floating point number and vice versa.

int integer = 42;
double floating = static_cast<double>(integer);

2. Pointer type conversion

static_cast Can be used to perform conversions between pointer types, but it is generally not checked at runtime . Therefore, you need to ensure that the conversion is safe

Parent* parentPtr = new Child;
Child* childPtr = static_cast<Child*>(parentPtr);

If you try to convert a pointer to a base class of a class to a pointer to a derived class , but the object is not actually an instance of the derived class, the conversion is unsafe.

class Base {};
class Derived {};

Base* basePtr = new Base;
Derived* derivedPtr = static_cast<Derived*>(basePtr); // 不安全

In this case, since the object is not actually Derivedan instance of the class, the conversion results in undefined behavior.

3. Upcasting in the class hierarchy

When you have a pointer to a derived class object but need to convert it to a base class pointer, you can use static_castupcasting .

Child* childPtr = new Child;
Parent* parentPtr = static_cast<Parent*>(childPtr);

2.dynamic_cast

dynamic_castIt is a type conversion operator in C++. It is mainly used to perform safe upward or downward type conversion in the class inheritance hierarchy and perform runtime type checking. Dynamic_cast can only be used for classes with virtual functions.

effect:

Safe downcast :

  1. You can use downcasting when you have a pointer or reference to a base class object , but know that it actually points to an object of a derived classdynamic_cast . It performs type checking at runtime to ensure that the conversion is safe.
  2. If the base class pointer or reference does not point to an object of the derived class , dynamic_cast will return nullptr (for pointers) and raise a std::bad_cast exception (for references) when downcasting.
class Base {};
class Derived : public Base {};

Base* basePtr = new Derived;
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
if (derivedPtr) {
    // 转换成功,可以安全地使用 derivedPtr
} else {
    // 转换失败
}

 

Runtime type checking :

dynamic_cast Runtime type checking is performed when performing type conversion to ensure that the actual type of the object matches the requested type. If the types do not match , it returns a null pointer (for pointer types) or throws std::bad_castan exception (for reference types). Incorrect type conversion can be avoided and the robustness of the program can be improved.

Here are dynamic_castthe basic uses of :

class Base {
public:
    virtual ~Base() {}
};

class Derived : public Base {
public:
    void derivedFunction() {
        // 派生类特有的函数
    }
};

int main() {
    Base* basePtr = new Derived;

    Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);
    if (derivedPtr) {
        // 转换成功,可以安全地访问派生类成员
        derivedPtr->derivedFunction();
    } else {
        // 转换失败
    }

    delete basePtr;
    return 0;
}

Why can dynamic_cast only be used for classes with virtual functions?

  • dynamic_cast Is a mechanism that performs type checking at runtime . It needs to know the actual type of the object in order to perform safe type conversions
  • Every class with virtual functions has a virtual function table, which stores pointers to various virtual functions. This virtual function table allows the actual type of the object to be looked up at runtime.

Summary: Use the virtual function table pointer to determine the actual type of the object at runtime

3.const_cast

const_cast Is a type conversion operator in C++, which is used to add or remove constqualifiers of objects to perform type conversion under certain conditions.

effect:

1. Remove constthe qualifier

The most common use is for converting consta pointer or reference of type to a non- consttype , which can allow the original constobject to be modified, but needs to be used with caution as it can lead to inconsistent behavior.

const int x = 42;
int* ptr = const_cast<int*>(&x);
*ptr = 55; // 可以修改 x,但是这是不推荐的

Inconsistent behavior occurs:

Violation of design convention : In some programming, using constis a convention used to indicate that an object should be considered immutable. If this convention is violated, errors in the program may result.

2.Add constqualifier

constA pointer or reference of a non-type can be converted to consta type , which is typically used when passing a read-only reference or pointer to an object to prevent the object from being modified inside a function.

int y = 10;
const int* constPtr = const_cast<const int*>(&y);

4.reinterpret_cast

概念:

reinterpret_castIs a type conversion operator in C++ that is used to perform low-level type conversions, usually used to convert between different types , or to treat integer values ​​as pointers . reinterpret_castVery powerful, but also very dangerous because it does no type checking.

The role of reinterpret_cast

1. Conversion between pointers

reinterpret_cast Can be used to convert one pointer type to another pointer type , even if there is no inheritance relationship between them.

int value = 42;
double* doublePtr = reinterpret_cast<double*>(&value);

This conversion does not perform any type checking, so you need to ensure that the conversion is safe. 

2. Conversion between integers and pointers

reinterpret_cast can also be used to convert an integer value to a pointer , or a pointer to an integer value. This is typically used for low-level programming or handling hardware interfaces

int integer = 42;
void* voidPtr = reinterpret_cast<void*>(integer);

3. Conversion between pointers of different types

Sometimes it is necessary to convert a pointer of one type to a pointer of another type, but be aware that this may lead to undefined behavior because it assumes a specific memory layout.

struct A { int x; };
struct B { double y; };

A* aPtr = new A;
B* bPtr = reinterpret_cast<B*>(aPtr); // 潜在的未定义行为

What is the difference between static_cast and dynamic_cast?

1. Period of type conversion

  • static_cast is a type conversion performed at compile time
  • dynamic_cast is a type conversion performed at runtime. It performs runtime type checking to ensure that the conversion is safe

2. Security

  • static_cast down conversion is unsafe : a pointer to a base class is converted to a pointer to a derived class, but in fact the object is not an instance of the derived class, then this conversion is unsafe
  • Dynamic_cast down conversion safety : During runtime, it will check if the base class pointer or reference does not point to an object of the derived class. When performing down conversion, dynamic_cast will return nullptr (for pointers) and raise a std::bad_cast exception (for references).

3. Scope of application

  • static_cast is suitable for conversion of non-polymorphic types, conversion between basic data types, and conversion between pointer types.
  • dynamic_cast is mainly used to handle conversions between polymorphic types. The object must contain at least one virtual function

Guess you like

Origin blog.csdn.net/sjp11/article/details/133554629