C++——类型转换

一、类型转换 (Type Conversion)

1. 显示转换 (Explicit Conversion)

  • C风格类型转换

    • 改进前: 试图将一个字符串转换为整数,可能导致数据丢失或程序崩溃

      c++ 复制代码
      #include <iostream>
      using namespace std;
      
      int main() {
        const char* str = "123";
        int a = int(str); // 错误!不能直接将字符串指针转换为 int
        cout << "a = " << a << endl;
        return 0;
      }
    • 改进后: 使用 std::stoi 函数将字符串转换为整数

      c++ 复制代码
      #include <iostream>
      #include <string>
      using namespace std;
      
      int main() {
        string str = "123";
        int a = std::stoi(str); 
        cout << "a = " << a << endl;
        return 0;
      }
  • static_cast (C++风格类型转换)

    • 改进前: 试图将一个基类指针转换为派生类指针,如果没有进行动态类型转换可能会导致未定义行为

      c++ 复制代码
      #include <iostream>
      using namespace std;
      
      class Base {};
      class Derived : public Base {};
      
      int main() {
        Base* b = new Base();
        Derived* d = static_cast<Derived*>(b); // 错误!b 实际指向 Base 对象
        delete d; // 未定义行为
        return 0;
      }
    • 改进后: 使用 dynamic_cast 进行安全的向下转型,如果转换不成功会返回 nullptr

      c++ 复制代码
      #include <iostream>
      using namespace std;
      
      class Base {};
      class Derived : public Base {};
      
      int main() {
        Base* b = new Derived();  // 现在 b 指向 Derived 对象
        Derived* d = dynamic_cast<Derived*>(b); // 安全的向下转型
        if (d) { 
          cout << "Successful downcasting." << endl;
          delete d; 
        } else {
          cout << "Failed downcasting." << endl;
        }
        return 0;
      }

2. 隐式转换 (Implicit Conversion)

  • 改进前: 将一个超出范围的值赋给较小的数据类型, 导致数据丢失

    c++ 复制代码
    #include <iostream>
    using namespace std;
    
    int main() {
        int i = 300;
        char c = i; // 警告:数据丢失,因为 char 只能存储 -128 到 127 的值
        cout << "c = " << c << endl; 
        return 0;
    }
  • 改进后: 在赋值之前进行范围检查, 避免数据丢失

    c++ 复制代码
    #include <iostream>
    using namespace std;
    
    int main() {
        int i = 300;
        if (i >= -128 && i <= 127) {
            char c = i; 
            cout << "c = " << c << endl; 
        } else {
            cout << "Value out of range for char type." << endl;
        }
        return 0;
    }

二、自定义类型转换

  • 改进前: 如果没有定义 Animal 到 Dog 的转换构造函数,则无法进行隐式类型转换

    c++ 复制代码
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Animal {
    public:
        Animal(const string& name) : name_(name) {}
        virtual void speak() const { cout << "Animal speaking" << endl; }
        string getName() const { return name_; }
    private:
        string name_;
    };
    
    class Dog : public Animal {
    public:
        Dog(const string& name) : Animal(name) {}
        // 没有定义 Animal 到 Dog 的转换构造函数
        void speak() const override { cout << "Woof!" << endl; }
    };
    
    int main() {
        Animal animal{"Buddy"};
        Dog dog = static_cast<Dog>(animal);  // 错误:无法进行隐式类型转换
        dog.speak();
    
        delete animal;
        return 0;
    }
  • 改进后: 定义从 Animal 到 Dog 的转换构造函数,允许隐式类型转换

    c++ 复制代码
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    class Animal {
    public:
        Animal(const string& name) : name_(name) {}
        virtual void speak() const { cout << "Animal speaking" << endl; }
        string getName() const { return name_; }
    private:
        string name_;
    };
    
    class Dog : public Animal {
    public:
        Dog(const string& name) : Animal(name) {}
        Dog(const Animal& a) : Animal(a.getName()) {} // 转换构造函数
        void speak() const override { cout << "Woof!" << endl; }
    };
    
    int main() {
        Animal animal{"Buddy"};
        Dog dog = animal; 
        dog.speak(); // 输出 "Woof!"
    
        return 0;
    }
相关推荐
乌暮30 分钟前
从 `println` 到生产级日志:Spring Boot 日志体系完全指南
java·开发语言·jvm·spring boot·后端·学习·面试
打工仔折腾 AI1 小时前
260+异构同步链路实战:如何用语义化自动翻译破解CDC DDL同步痛点
人工智能·后端·python·自然语言处理·性能优化·langchain·机器翻译
松就是我902981 小时前
Agent工具调用实现原理
后端
学习的老炮1 小时前
反汇编基础速记
后端
步行cgn2 小时前
@RequestMapping 注解详解
java·后端·spring
骑着蜗牛撵大象3272 小时前
设备监控数据存与查:Spring Boot 接入 TimescaleDB 超表的完整落地
android·spring boot·后端·springboot·时序数据库·es·设备监控
鶴哥只手遮天2 小时前
Spring Boot 4.1.1 深度源码解析-第 15 章 · 条件注解体系:全部 `@ConditionalOnXxx` 的实现原理
java·后端·开源
我的div丢了肿么办2 小时前
go语言安装包详细讲解
后端·go
鶴哥只手遮天2 小时前
Spring Boot 4.1.1 深度源码解析-第 30 章 · 基础设施能力:SSL Bundle、Task 与虚拟线程、Retry
java·后端·开源
Zenova EdgeOS2 小时前
Rust TUI 实战:用 ratatui 构建工业边缘终端界面
开发语言·后端·rust·工业网关