总结

去常转换:const_cast:指针或者引用 去常或者加常
静态转换:static_cast:基本类型转换 子转父安全 父转子不安全 无类型检查
重新解释:reinterpret_cast:任何指针互相转换 不安全
动态转换:dynamic_cast:子转父安全 父转子有类型检查必须有虚方法

去常转换:const_cast

把常量指针或常量引用 转换 为非常量指针或非常量引用
把非常量指针或非常量引用 转换 为常量指针或常量引用
强制转换类型必须是指针*或引用&。

#include<iostream>
using namespace std;
int main()
{
   const int a = 10;
   const int& b = 20;
   //去常
   int &ra = const_cast<int&>(a);
   int *pb = const_cast<int*>(&b);
   cout<<ra<<" "<<*pb<<endl;

   //加常
   const int &c = const_cast<const int&>(ra);
   const int* d = const_cast<const int *>(pb);
   cout<<c<<" "<<*d<<endl;

   //int cc = const_cast<int>(a);  错误
   //int dd = const_cast<int>(b);  错误
    return 0;
}

静态转换:static_cast

基本类型转换+基本类型指针间转换(void)*

#include<iostream>
using namespace std;
int main()
{
	//基本类型转换
   float ft = 12.5f;
   int a = static_cast<int>(ft);
   cout<<a<<endl;//输出12

	//无类型指针转换 不安全 容易出错
   int number = 100;
   char *b = static_cast<char*>((void*)&number);
   int* jieguo = static_cast<int*>((void*)b);
   cout<<*jieguo<<endl;//输出100
    return 0;
}

派生类转化为基类(安全) + 基类转化为派生类(不安全)

#include<iostream>
using namespace std;
class Object
{
public:
    Object(int x = 0):value(x)
    {
    }
    void printObject()const {cout<<value<<endl;}
private:
    int value;
};

class Base:public Object
{
public:
    Base(int x):Object(x+10),num(x)
    {
    }
    void printBase()const {cout<<num<<endl;}
private:
    int num;
};
int main()
{
    Object obj(10);
    Base base(20);

    //上行转换 安全
    obj = static_cast<Object>(base);
    obj.printObject();//输出30
    Object* op = static_cast<Object*>(&base);
    op->printObject();//输出30

    //下行转换 不安全
    //base = static_cast<Base>(obj);//错误
    Base* bp = static_cast<Base*>(&obj);//输出-1497351504
    bp->printBase();
  
    return 0;
}

重新解释:reinterpret_cast

任何指针都可以转换成其它类型的指针

#include<iostream>
using namespace std;
class Test{};
class Base{};
int main()
{
  int a = 10;
  float* fp = reinterpret_cast<float*>(&a);
  cout<<*fp<<endl;//1.4013e-44

  Base b;
  Test* tp = reinterpret_cast<Test*>(&b);//不安全
    return 0;
}

动态转换:dynamic_cast

从派生类到基类的转换:当已知对象的实际类型时,可以直接转换。
从基类到派生类的转换:在这种情况下,dynamic_cast 会在运行时检查对象的实际类型是否与指定的派生类类型匹配。如果不匹配,dynamic_cast 会返回一个空指针或保持原来的引用不变(对于引用而言)。

注意:
1.dynamic_cast 只能在具有虚函数的类中使用,因为需要运行时类型信息来进行类型检查。因此,如果基类中没有虚函数,dynamic_cast 将无法正常工作。
2.当转换失败时,对于指针,dynamic_cast 返回 nullptr;对于引用,如果转换失败则会抛出 std::bad_cast 异常。

转换成功例子:

#include <iostream>

class Base {
public:
    virtual ~Base() {}
    virtual void print() { std::cout << "Base\n"; }
};

class Derived : public Base {
public:
    void print() override { std::cout << "Derived\n"; }
};

int main() {
    Derived derivedObj;
    Base *basePtr = &derivedObj;

    // 使用 dynamic_cast 进行安全的向下转换
    Derived *derivedPtr = dynamic_cast<Derived*>(basePtr);

    if (derivedPtr != nullptr) {
        derivedPtr->print(); // 输出 "Derived"
    } else {
        std::cout << "Conversion failed.\n";
    }

    return 0;
}

转换失败例子:

#include <iostream>

class Base {
public:
    virtual ~Base() {}
    virtual void print() { std::cout << "Base\n"; }
};

class Derived : public Base {
public:
    void print() override { std::cout << "Derived\n"; }
};

int main() {
    Base *basePtr = new Base();
    Derived *derivedPtr = dynamic_cast<Derived*>(basePtr);

    if (derivedPtr != nullptr) {
        derivedPtr->print(); // 不会被调用,因为转换失败
    } else {
        std::cout << "Conversion failed.\n";
    }

    delete basePtr;

    return 0;
}

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部