C++2.0

c++11智能指针父类指针转换为子类指针

2018-08-23  本文已影响113人  dnsir

1 C语言指针类型转换

C语言中的指针就是裸指针,裸指针存储是指向计算机内存的某一(起始)地址,通过*取值操作符可以进行任何操作,因此不同指针类型相互转换是比较简单的事情,如下代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    char c = 'a';
    printf("c = %i\n", c);

    int * ip1 = (int *)&c; //指针转换
    printf("ip = %p\n", ip1);
    printf("i = %c\n", *ip1);
    printf("i = %i\n", *ip1);

    //
    int a = (int)c;  //强转
    printf("a = %d\n", a);

    exit(0);
}

转换之后,开发者只要知道类型就可以对原有数据进行各类操作,C语言最强大的void *类型经常作为函数参数类型。

2 C++指针类型相互转换

C++中是允许裸指针,因此裸指针之间转换方法同C语言指针强转,C++11中引入了智能指针std::shared_ptr等,boost库种也有类似智能指针boost::shared_ptr,智能指针转换不能通过上述方法进行强转,必须通过库提供转换函数进行转换。
C++11的方法是:std::dynamic_pointer_cast, boost中的方法是:boost::dynamic_pointer_cast。如下代码所示:


#include <memory>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <iostream>

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

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

int main()
{
    // derived class to base class
    D* d1 = new D();
    Base* b1 = d1;
    //
    std::shared_ptr<D> d2 = std::make_shared<D>();
    std::shared_ptr<Base> b2 = d2;

    boost::shared_ptr<D> d3 = boost::make_shared<D>();
    boost::shared_ptr<Base> b3 = d3;

    /*
     * dynamic cast maybe failed. and return null;
     * 
     */
    D* d11 = dynamic_cast<D*>(b1); //succ
    D* d12 = static_cast<D*>(b1);  //succ
    
    typedef std::shared_ptr<D> d_ptr;
    // std::shared_ptr<D> d21 = dynamic_cast<d_ptr>(b2); //compile error
    std::shared_ptr<D> d22 = std::dynamic_pointer_cast<D>(b2);

    typedef boost::shared_ptr<D> d_b_ptr;
    // boost::shared_ptr<D> d31 = dynamic_cast<d_b_ptr>(b3); //compile error
    boost::shared_ptr<D> d32 = boost::dynamic_pointer_cast<D>(b3);
    return 0;
}

本代码示例下载地址

2.1 C++智能指针强转应用场景

如上述代码,假如定义一个map用来保存所有的实例:

std::unordered_map<int id, std::shared_ptr<Base>>  objs;
objs.insert[1] = d21;
//拿出来的对象类型是D
std::shared_ptr<Base> o = objs[1];
//此处需要强转
//std::shared_ptr<D> dd = o; //compile error
std::shared_ptr<D> dd = std::dynamic_pointer_cast<D>(o);
//然后就可以正常调用类D所有的成员函数
上一篇下一篇

猜你喜欢

热点阅读