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;
    }
相关推荐
孙启超4 分钟前
【AI开发之Rust】第 13 课:async/await 与 tokio 异步运行时
开发语言·后端·rust
SimonKing15 分钟前
SpringBoot 集成 SSE 实现服务端推送或可代替Websocket
java·后端·程序员
字节探索15 分钟前
Redis 只会当缓存用?这 10 大实战场景,让你的系统快到飞起
redis·后端
Sam_Deep_Thinking34 分钟前
关于java final关键字的可见性
java·后端·面试·程序员
Thneonl40 分钟前
你的 Pod 为什么 Pending:调度器两阶段
后端·kubernetes
zihan5181 小时前
自己做软件日记9/21 得到了一个良好的文件结构框架
后端·flutter·前端框架·android studio
乌暮2 小时前
Java 抽象类与接口详解:半成品图纸 vs 能力合同
java·开发语言·后端·学习
一条泥憨鱼2 小时前
苍穹外卖【day12| 工作台,通过Apache POI导入/导出运营数据】
java·后端·苍穹外卖
IT_陈寒2 小时前
Redis大key删除引发的服务雪崩,这次我真记住了
前端·人工智能·后端
努力的小雨2 小时前
10 个任务拆成 22 项能力,Seed 2.1 Pro 哪些方向值得用?
后端