C++强制类型转换运算符-dynamic_cast、const_cast、static_cast、reinterpret_cast

代码及说明:
main.cpp

#include 
#include 
#include 
#include "rtti1.h"
using std::cout;
using std::endl;

Grand *GetOne();
void change(const int *pt, int n);
int main()
{
    /*
    dynamic_cast:
        dynamic_cast是最常用的RTTI操作符。
        回答的问题:是否能将某个对象的地址安全地赋值给一个特定类型的指针;同时也回答了强制类型转换是否安全的问题
        格式:dynamic_cast(pt)
            pt能否安全的类型转换(*pt为Type或者*pt为Type的继承类)为Type *,如果可以,则返回pg的地址;反之,返回0
        也可以使用引用(应该不常用):dynamic_cast(rg)
            pt能否安全的类型转换(pt为Type或者pt为Type的继承类)为Type &,如果可以,则返回pg的地址;反之,引发bad_cast异常(在typeinfo头文件中)
    */
    cout << "dynamic_cast***************************************************************" << endl;
    std::srand(std::time(0));
    Grand *pg;
    Superb *ps;
    for (int i = 0; i < 5; i++)
    {
        pg = GetOne();
        pg->Speak();
        if (ps = dynamic_cast<Superb *>(pg)) // 如果可以转换,则if条件判断为1,则执行ps->Say();反之,不执行
            ps->Say();
    }
    /*
    const_cast:
        转换格式:const_cast < type-name > (expression)
        要求:type-name和expression必须是同一种类型,他们只在const和volatile上存在区别,转换成功就赋值就行,转换失败则返回0
        与常规类型转换的不同:常规类型转换可以转换为不同类型,但是const_cast不允许不同类型的转换
        基本原则:不允许将定义为const的变量转换为非const类型。
    */
    cout << "const_cast***************************************************************" << endl;
    int pop1 = 38383;
    const int pop2 = 2000;
    cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl;
    change(&pop1, -103); // 转换了,因为pop1是非const类型
    change(&pop2, -103); // 没转换,因为pop2是const类型
    cout << "pop1, pop2: " << pop1 << ", " << pop2 << endl;
    /*
    static_cast:
        格式:static_cast < type-name > (expression)
        当且仅当type-name类型可以隐式转换为expression类型,或反之,否则类型转换会报错,两者能互相转换
        1.允许向上转换(继承类指针转换为基类指针)
        2.允许向下转换(基类指针转换为继承类指针)
        3.由于枚举类可以隐式转换为int,因此static_cast允许这类转换,并且允许将int类型转换为枚举类
        4.允许将double转换为int,将int转换为double
        5.允许将float转换为long,允许将long转换为float
    */
    cout << "static_cast***************************************************************" << endl;
    Grand x = Grand(10);   // 基类对象
    Grand *w = &x;         // 基类指针
    Superb z = Superb(11); // 继承类对象
    Superb *pointer1 = &z;
    Superb *y = static_cast<Superb *>(w);      // 将基类指针转换为继承类指针 允许
    y->Speak();                                // 只是允许但是不推荐,因为转换为继承类指针后可以调用继承类的成员方法,而基类没有该成员方法,会引发异常
    Grand *a = static_cast<Grand *>(pointer1); // 将继承类指针转换为基类指针
    a->Speak();
    int varint1 = 99;
    double vardouble1 = 99.99;
    int var = static_cast<int>(vardouble1);
    std::cout << "var = " << var << std::endl;
    double var1 = static_cast<double>(varint1);
    std::cout << std::fixed << "var1 = " << var1 << std::endl;
    /*
    reinterpret_cast:
        格式:reinterpret_cast < type-name > (expression)
        可以将指针类型转换为能够容纳该指针类型的整型,反之不能转换。
        不能将函数指针转换为数据指针
    */
    struct dat
    {
        short a;
        short b;
    };
    long value = 0xA224B118;
    dat *pd = reinterpret_cast<dat *>(&value);
    std::cout << std::hex << pd->a; // display first 2 bytes of value

    return 0;
}
Grand *GetOne() // generate one of three kinds of objects randomly
{
    Grand *p = 0;
    switch (std::rand() % 3)
    {
    case 0:
        p = new Grand(std::rand() % 100);
        break;
    case 1:
        p = new Superb(std::rand() % 100);
        break;
    case 2:
        p = new Magnificent(std::rand() % 100,
                            'A' + std::rand() % 26);
        break;
    }
    return p;
}

void change(const int *pt, int n)
{
    int *pc;
    pc = const_cast<int *>(pt);
    *pc += n;
}

rtti1.h

#pragma once
#include 
using std::cout;
#ifndef _RTTI1_H_
#define _RTTI1_H_
class Grand
{
private:
    int hold;

public:
    Grand(int h = 0) : hold(h) {}
    virtual void Speak() const { cout << "I am a grand class!\n"; }
    virtual int Value() const { return hold; }
};
class Superb : public Grand
{
public:
    Superb(int h = 0) : Grand(h) {}
    void Speak() const { cout << "I am a superb class!!\n"; }
    virtual void Say() const
    {
        cout << "I hold the superb value of " << Value() << "!\n";
    }
};
class Magnificent : public Superb
{
private:
    char ch;

public:
    Magnificent(int h = 0, char c = 'A') : Superb(h), ch(c) {}
    void Speak() const { cout << "I am a magnificent class!!!\n"; }
    void Say() const
    {
        cout << "I hold the character " << ch << " and the integer " << Value() << "!\n";
    }
};
#endif

你可能感兴趣的:(c++,算法,开发语言)