C ++ STL-- cast

table of Contents


Note: The original is not easy, reproduced, please be sure to indicate the source and author, thanks for the support!
Note: content from a training course, may not be entirely correct!

A type conversion

Type conversion variable so as to change the meaning of another type by changing the type of a variable representation. C ++ provides four conversion operator to deal with different situations type conversion.

grammar Applicable scene
static_cast General conversion (such as C ++ built conversion between types)
dynamic_cast Is generally used when converting between the base and derived classes
const_cast Mainly for const conversion
reinterpret_cast No conversion for any correlation between such a character pointer to an integer number


Summary:
(1) static_castfor converting the built-in data types, inheritance with pointers or references.
(2) dynamic_castcan only convert a pointer or reference to the inheritance, and can only be transferred by the sub-type to the parent type (base type). On the basis of the relationship between the conversion with a pointer or reference, compared to static_cast, dynamic_cast, adding extra security checks, rejected the unsafe type conversion, more safe.
(3) const_castused to the underlying data type, a pointer or reference to "add" or "removing" const
(. 4) reinterpret_castfor any type of two independent pointer or reference conversion

As shown in a detailed case studies on C ++ type conversion as follows.


class Building {};
class Animal {};
class Cat : public Animal {};

void Test1()
{
    // static_cast
    int a = 65;
    char c = static_cast<char>(a);
    cout << c << endl;

    // 基础数据类型的指针 - 无法转换
    // int *p = nullptr;
    // char *sp = static_cast<char *>(p);

    // 对象指针 - 无法转换
    // Building *building = nullptr;
    // Animal *ani = static_cast<Animal *>(building);

    // 转换具有基础关系的对象指针
    // 父类指针转子类指针
    Animal *ani = nullptr;
    Cat *cat = static_cast<Cat *>(ani);
    // 子类指针转父类指针
    Cat *soncat = nullptr;
    Animal *anifather = static_cast<Animal *>(soncat);
    // 父类引用转子类引用
    Animal aniobj;
    Animal &aniref = aniobj;
    Cat &catref = static_cast<Cat &>(aniref);
    // 子类引用转父类引用
    Cat catobj;
    Cat &catref2 = catobj;
    Animal & aniref2 = static_cast<Animal &>(catref2);

    // 总结:static_cast用于内置数据类型,具有继承关系的指针或者引用的转换
}

void Test2()
{
    // dynamic_cast只能转换具有继承关系的指针或者引用
    // 其在转换之前会进行对象类型的检查

    // 内建数据类型的转换 - 无法转换
    // dynamic_cast中的类型必须是指向完整类类型或者void *的指针或者引用
    // int a = 10;
    // char c = dynamic_cast<char>(a);

    // 非继承关系的指针的转换 - 无法转换,两者不具备继承关系
    // Animal *pani = nullptr;
    // Building *pbuilding = dynamic_cast<Building *>(pani);

    // 具有继承关系的指针 - 无法转换,父类指针转子类指针是类型不安全的
    // Animal *pani = nullptr;
    // Cat *pcat = dynamic_cast<Cat *>(pani);

    // 具有继承关系的指针 - 可以转换,子类指针转换为父类指针是类型安全的
    Cat *pcat = nullptr;
    Animal *pani = dynamic_cast<Animal *>(pcat);

    // 具有基础关系的引用 - 无法转换,原因同样是父类引用转换成子类引用是类型不安全的
    // Animal aniobj;
    // Animal &aniref = aniobj;
    // Cat &catref = dynamic_cast<Cat &>(aniref);

    // 具有继承关系的引用 - 可以转换,子类引用转父类引用是类型安全的
    Cat catobj;
    Cat &catref = catobj;
    Animal &aniref = dynamic_cast<Animal &>(catref);

    // 总结:dynamic_cast只能转换具有继承关系的指针或者引用
    // 并且只能由子类型转成父类型(基类型)
    // 在具有基础关系的指针或者引用的转换上,相较于static_cast,dynamic_cast
    // 添加了额外的安全检查,拒绝了类型不安全的转换,更加地安全
}

void Test3()
{
    // 基础数据类型
    int a = 10;
    const int &b = a;
    // b = 20; b为const引用,无法通过b来修改a的值
    // 通过const_cast去除const
    int &c = const_cast<int &>(b);
    // 通过引用c来修改a的值
    c = 20;
    // a值为20现在
    cout << "a = " << a << endl;

    // 指针
    // 去除const
    const int *p1 = nullptr;
    int *p2 = const_cast<int *>(p1);

    // 加上const
    int *p3 = nullptr;
    const int *p4 = const_cast<const int *>(p3);

    // 引用 - 去除const
    int k = 20;
    const int &r1 = k;
    int &r2 = const_cast<int &>(r1);

    // 引用 - 加上const
    int j = 30;
    int &r3 = j;
    const int &r4 = const_cast<const int &>(r3);

    // 总结:const_cast用来给基础数据类型,指针或者引用“加上”或者“去除”const
}

typedef void(*func1)(int, int);
typedef int(*func2)(int, char*);

void Test4()
{
    // 基础数据类型 - 无法转换
    // int a = 10;
    // char c = reinterpret_cast<char>(a);

    // 指针
    Building *pbuilding = nullptr;
    Animal *ani = reinterpret_cast<Animal *>(pbuilding);

    // 引用
    Building building;
    Building &bref = building;
    Animal &aniref = reinterpret_cast<Animal &>(bref);

    // 函数指针
    func1 f1;
    func2 f2 = reinterpret_cast<func2>(f1);

    // 总结:reinterpret_cast用于任意两个无关类型的指针或者引用的转换!
    // 应该尽量避免在代码中使用类型转换!!!
}

Guess you like

Origin www.cnblogs.com/laizhenghong2012/p/11773751.html