C 语言

关注公众号 jb51net

关闭
首页 > 软件编程 > C 语言 > C++强制类型转换

C++引用和强制类型转换问题小结

作者:和编程干到底

本文给大家介绍C++引用和强制类型转换问题,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

引用

引用是变量的别名,操作引用等同于操作原变量(共享同一块内存)

语法:数据类型 &引用名 = 原变量名

#include <iostream>
#include<string>
using namespace std;
int main()
{
    int a = 20;
    int& b = a; b是a的引用(别名)
    cout << "a=" << a << ",b=" << b << endl;
    cout << "a的地址" << &a << ",b的地址" << &b << endl;
    b = 20;
    cout << "a=" << a << ",b=" << b << endl;
    return 0;
}

1. **定义方式**:使用 `&` 符号声明引用

int a = 10; int &ref = a; ref 是变量 a 的引用(别名)

2. **必须初始化**:引用在声明时必须初始化,不能像指针一样先声明后赋值

int &ref; 错误!引用必须初始化

3. **一旦绑定,不能更改**:引用一旦与某个变量绑定,就不能再改为引用其他变量

int a = 10, b = 20; int &ref = a; ref 引用 a ref = b; 这是将 b 的值赋给 a,而不是让 ref 引用 b

4. **操作引用即操作原变量**:对引用的任何操作都会直接影响原变量

int a = 10; int &ref = a; ref++; 等价于 a++ cout << a; 输出 11

引用的应用场景

1. **作为函数参数**:避免参数传递时的拷贝,提高效率,同时允许函数修改实参

void swap(int &x, int &y) 
{ int temp = x; x = y; y = temp; } 调用时直接传递变量,而非指针 int a = 10, b = 20; swap(a, b); a 和 b 的值会被交换

2. **作为函数返回值**:可以返回函数内部静态变量或外部变量的引用,允许链式操作

int &max(int &x, int &y) {
    return (x > y) ? x : y;
}
int a = 10, b = 20;
max(a, b) = 30;   将较大的变量(b)赋值为 30

3. **在类中使用**:常用于运算符重载和避免对象拷贝

class MyClass {
private:
    int value;
public:
    MyClass(int v) : value(v) {}
    int &getValue() { return value; }   返回成员变量的引用
};
MyClass obj(10);
obj.getValue() = 20;   通过引用修改私有成员变量   

引用与指针的区别

注意事项

1. 不要返回局部变量的引用,因为局部变量在函数结束后会被销毁,引用会变成悬空引用

int &badFunction() {
    int x = 10;
    return x;    错误!返回局部变量的引用
}  

2. 可以声明常量引用(`const` 引用)来引用常量或临时值

const int &ref1 = 100;   合法
const int &ref2 = a + b;   合法,引用表达式结果

3. 引用可以用于任何基本类型、自定义类型,甚至数组和函数

引用提供了一种简洁、安全的方式来操作变量,在很多情况下可以替代指针,使代码更易读、更安全。但也要注意其使用限制,避免出现悬空引用等问题。

本质

C++中,引用的底层实现是指针常量( int*const p)指针的指向不可改,但指向的值可以改。编译器会自动将引用操作转换为指针操作,因此引用的语法更简洁,但本质和指针类似。

int a=10; int&b=a; 等价于int*const b=&a; b=20; 等价于*b=20;

常量引用

作用:防止通过引用修改原变量(用于保护实参),通常修饰函数形参。

语法:const数据类型 &引用名 = 原变量;

1、定义方式:在引用声明前加 const 关键字
int a = 10;
const int &ref = a;   ref 是常量引用,绑定到 a
2、不能通过常量引用修改原变量:
int a = 10;
const int &ref = a;
ref = 20;   错误!常量引用不允许修改所引用的变量
a = 20;     合法!原变量本身可以被修改(除非原变量也是 const)
3、可以引用常量或临时值:普通引用不能直接引用常量或表达式结果,但常量引用可以
const int &ref1 = 100;        合法,常量引用可以引用字面量
const int &ref2 = 5 + 3;      合法,引用表达式结果
const int &ref3 = a * 2;      合法,引用变量运算结果

强制类型转换

1. static_cast:静态类型转换(最常用)

示例:

nt a = 10;
double b = static_cast<double>(a);   基本类型转换
class Base {};
class Derived : public Base {};
Derived d;
Base* b_ptr = static_cast<Base*>(&d);   子类指针→父类指针(安全)

2. dynamic_cast:动态类型转换(运行时检查)

运行

class Base { virtual void f() {} };   含虚函数,多态类型
class Derived : public Base {};
Base* b = new Derived;
Derived* d = dynamic_cast<Derived*>(b);   父类→子类,安全,返回非空指针
下面写法不推荐
Base* b2 = new Base;
Derived* d2 = dynamic_cast<Derived*>(b2);   不安全,返回 nullptr
#include <string>
#include <iostream>
using namespace std;
class Father
{
public:
    virtual void fun()
    {
        cout << "我是父类" << endl;
    }
};
class Son : public Father
{
public:
    void fun()
    {
        cout << "我是子类" << endl;
    }
};
int main()
{
     1、向下转型父类指向子类
    Father *father = new Son;
    Son *son = dynamic_cast<Son *>(father);
    son->fun();
     2、向下转型父类指向父类  不安全,返回 nullptr
    Father *father1 = new Father;
    Son *son1 = dynamic_cast<Son*>(father1);
    if (son1==nullptr)
    {
        cout<<"我是空指针"<<endl;
    }
    return 0;
}

3. const_cast:常量性转换

运行

const int* p = new int(10);
int* q = const_cast<int*>(p);   移除 const 限定
*q = 20;   若原对象(*p)非 const,则合法;若原对象是 const,则 UB
 去除const属性之后还是共用同一块内存
    int b=20;
    const int *p=&b;
    cout<<*p<<endl;
    int *p1=const_cast<int*>(p);
    *p1=40;
    cout<<*p<<endl;

4. reinterpret_cast:重新解释类型转换(最危险)

运行

int a = 0x12345678;
int* p = &a;
double* q = reinterpret_cast<double*>(p);  重新解释指针类型(危险)

总结

到此这篇关于C++引用和强制类型转换问题小结的文章就介绍到这了,更多相关C++强制类型转换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文