实验E10:强制类型转化、类成员指针(static_cast, const_cas,t reinterpret_cast的使用)

在这里插入图片描述

#include <iostream>
using namespace std;
class base {

public:
    int _val = 0;
    string name = "name";
    int _num = 5;
    bool _jud = true;
    base() {}
    base(int toval)
    {
        _val = toval;
    }
    void show() const
    {
        cout << "_val的值为" << _val << endl;
    }
    void change(int toval)
    {
        _val = toval;
    }
    int get_Zero()
    {
        return 0;
    }
    void f()
    {
        cout << "calling f()" << endl;
    }

};
//数据成员指针测试
template<typename T>

void print(base& _base, T base::* ptr)
{
    cout << (_base.*ptr) << endl;
}

//函数成员指针测试
typedef void (base::* ptr1)();//调用f()
typedef void (base::* ptr2)()const;//调用show()
typedef void (base::* ptr3)(int);//调用g(int)
typedef int (base::* ptr4)();//调用get_Zero()





class Derived : public base
{
public:
    void test()
    {
        cout << "calling Derived::test()" << endl;
    }
};

//函数指针测试
class compute
{
public:
    static double add(double a, double b)
    {
        return a + b;
    }
};

typedef double (*Compute)(double, double);//函数指针



int main() {

    //static_cast test 1
    Derived d1;
    base b1 = static_cast<base>(d1);//从子类向父类转化
    d1.show();
    d1.test();
    //static_cast test 2
    char ch = 'a';//字符a的ASC码是0x61,以下测试为基本数据成员的转化
    int t1 = static_cast<int>(ch);
    cout << t1 << endl << ch << endl;
    if (t1 == 0x61)
    {
        cout << "t1==0x61" << endl;
    }
    else
    {
        cout << "t1!=0x61" << endl;
    }

    //reinterpret_cast  test 1
    int b2 = 5;
    int* ptr = &b2;
    int t2 = reinterpret_cast<int>(ptr);//将ptr的值理解为一个int
    printf("%d\n%d\n", ptr, t2);//输出的值相等

  //reinterpret_cast  test 2
    base _re_b(1);//对reinterpret_cast在不同类型的引用之间的转换的测试
    int& n1 = reinterpret_cast<int&>(_re_b);
    cout << "原来的_val值是" << _re_b._val << endl;
    n1 = -100;
    cout << "修改n1为-100后,_val值为" << _re_b._val << endl;//初始化的时候为1,但是用int的引用n1,修改了_re_n为-100

    //reinterpret_cast  test 3
    int m1 = 1;
    cout << "原来的m1值为" << m1 << endl;
    base* _re_a = reinterpret_cast<base*>(&m1);
    _re_a->_num = -100;
    cout << "修改类内的第二个声明定义的_num变量为-100后,m1的值为" << m1 << endl;//这个时候还是1
    _re_a->_val = -100;
    cout << "修改类内的第一个声明定义的_val变量为-100后,m1的值为" << m1 << endl;//此时输出-100
    printf("_re_a->_val的地址为%p\n_re_a->_num的地址为%p\n", &_re_a->_val, &_re_a->_num);
    printf("m1的地址为%p\n", &m1);


    //reinterpret_cast  test 4 能容纳指针的整数之间的转换
    long long _re_l = 0x123456789abcd;
    cout << "_re_l的值为" << hex << _re_l << endl;
    base* _re_c = reinterpret_cast<base*>(_re_l);
    long long   _re_r = reinterpret_cast<long long>(_re_c);
    cout << "经过指针转化后的_re_r是" << hex << _re_r << endl;//输出了6789abcd,证明了逐个字节的拷贝


    //const_cast test 1
    {
        const int a = 12;
        const int* ap = &a;
        int* tmp = const_cast<int*>(ap);
        *tmp = 11;
        cout << "test1中a最后的值为" << a << endl; //输出12
    }
    //const_cast test 2
    {
        int a = 12;
        const int* ap = &a;
        int* tmp = const_cast<int*>(ap);
        *tmp = 11;
        cout << "test2中a最后的值为" << a << endl;//输出11
    }


    //const_cast test 3
    base _co_b1(5);
    const base* bptr = &_co_b1;
    base* base2 = const_cast<base*>(bptr);//常量指针被转换为非常量指针
    base2->change(-9);
    bptr->show();//输出-9,证明确实去掉了const属性


    //const_cast test 4
    {
        const base b3;
        base b4 = const_cast<base&>(b3);//常量引用被转化为非常量引用
        b4.change(7);
        b4.show();//7
        b3.show();//0,证明原来的b3并没有被修改
        printf("b4的地址为%d\n", &b4);
        printf("b3的地址为%d\n", &b3);//输出地址查看,不相同再次验证了猜测
    }
    {
        base b3;
        base& b4 = b3;
        b4.change(7);
        b4.show();//7
        b3.show();//7,证明原来的b3被修改了
        printf("b4的地址为%d\n", &b4);
        printf("b3的地址为%d\n", &b3);//输出地址查看,不相同再次验证了猜测

    }

    //打印数据成员指针的值
    string base::* nptr = &base::name;//类的数据成员指针
    int base::* nptr1 = &base::_num;
    bool base::* nptr2 = &base::_jud;

    //依次以十六进制打印数据成员指针的值
    printf("%x\n", nptr);
    printf("%x\n", nptr1);
    printf("%x\n", nptr2);


    //依次打印数据成员

    base temp;
    print(temp, nptr);
    print(temp, nptr1);
    print(temp, nptr2);

    //函数成员指针
    ptr1 _ptr1 = &base::f;
    ptr2 _ptr2 = &base::show;
    ptr3 _ptr3 = &base::change;
    ptr4 _ptr4 = &base::get_Zero;
    //打印函数成员指针的值
    printf("%x\n", _ptr1);
    printf("%x\n", _ptr2);
    printf("%x\n", _ptr3);
    printf("%x\n", _ptr4);

    //类函数成员的使用
    base b5;
    (b5.*_ptr1)();
    (b5.*_ptr2)();
    (b5.*_ptr3)(9);
    cout << "调用(b5.*_ptr3)(9)后" << endl;
    (b5.*_ptr2)();
    cout << (b5.*_ptr4)() << endl;

    Compute _Com = &compute::add;//普通函数指针应用
    cout << "调用普通函数指针的结果为" << _Com(9.2, 6) << endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值