现代C++教程之新特性nullptr和enum class 03

1 nullptr

        nullptr是C++11引入的关键字,用于表示空指针。

1.1 为什么要引入nullptr ?      

       在C++中,指针是一个特殊的数据类型,可以存储其它变量的地址。通常情况下,指针可以指向一个有效的地址,即指向有效的内存空间。然而,在某些情况下,我们希望将指针置为空,表示它不指向任何有效的地址。这在编程中是非常有用的,例如在函数中将指针初始化为空,然后在需要时再为其赋值。

       在C++11之前,通常使用NULL来表示空指针。但是,NULL是一个宏定义,同时也是整数常量0的别名。这意味着NULL在某些情况下可能会引发一些意外的行为。

        为了解决这个问题,C++11引入了nullptr关键字。nullptr的意思是“空指针”,它的类型是std::nullptr_t。nullptr可以用来初始化任何指针类型,且不会导致一些潜在的类型转换问题。同时,nullptr还支持与指针相关的比较操作。

1.2 nullptr的高级用法

  • 函数重载和模板推断

        nullptr可以帮助区分函数重载或模板推断的正确选择。在C++中,函数重载和模板推断时,往往需要根据参数类型来进行选择。如果我们使用NULL来表示空指针,编译器可能会将它解释成整数0,而不是指针类型。而使用nullptr作为参数则可以明确指示空指针。

void foo(int);
void foo(char*);

foo(nullptr);  // 调用void foo(char*)
  • 安全的类型转换

        nullptr在类型转换中更安全。在C++中,指针类型可以隐式转换为bool类型。如果我们使用NULL进行隐式转换,可能会导致一些意外行为,因为NULL实际上是一个整数常量0的别名。使用nullptr作为nullptr_t类型,可以确保只有指针类型可以隐式转换为bool类型。这使得代码更容易阅读和理解。

void foo(int);
void foo(bool);

foo(nullptr);  // 调用void foo(bool)
  • 安全的成员访问

        使用nullptr可以安全地进行成员访问操作。在C++中,我们可以使用指针访问成员变量或成员函数,但是如果指针为空,则会导致运行时错误。使用nullptr可以帮助我们在访问成员之前进行空指针检查,从而避免出现访问空指针的情况。

struct Foo {
    void bar() { std::cout << "I am bar!" << std::endl; }
};

Foo* ptr = nullptr;
if (ptr != nullptr) {
    ptr->bar();  // 进行空指针检查,避免访问空指针
}

2 强类型枚举(enum class)

        强类型枚举(enum class)是C++11中引入的一种新的枚举类型。与传统的枚举类型相比,强类型枚举具有更强的类型安全性和作用域限制。

        传统的枚举类型在C++中是一个整数类型,它的值可以隐式地转换为整型。这可能导致一些潜在的问题,如意外的类型转换和枚举值之间的命名冲突。为了解决这些问题,强类型枚举引入了新的语法和行为。

2.1 基本语法

        强类型枚举使用enum class关键字来定义,其基本语法如下:

enum class EnumName : underlying_type {

enumerator1,

enumerator2,

// ...

};

        其中:

  • EnumName是强类型枚举的名称,可以在命名空间内使用。
  • underlying_type是强类型枚举的潜在类型(underlying type),可以是intcharenum或其它整数类型。如果未指定潜在类型,则默认为int类型。
  • enumerator1enumerator2等是枚举类型的枚举值,它们归属于EnumName这个作用域。

        下面是一个强类型枚举的示例:

enum class Color : int {
    Red,
    Green,
    Blue
};

        在强类型枚举中,枚举值的作用域被限制在枚举类型的作用域内。这意味着我们不能直接将枚举值与其它整型值混合使用,也不能直接将枚举值隐式地转换为整型。

Color color = Color::Red;
int value = static_cast<int>(color);  // 需要显式的类型转换

if (color == Color::Green) {
    // ...
}

        这种强类型枚举的更严格的类型转换规则和作用域限制使得代码更加安全和可读,并且可以避免一些潜在的错误。当需要使用枚举类型时,推荐使用强类型枚举(enum class)来代替传统的枚举类型(enum)。

2.2 enum class常见用法

  • 枚举值的位操作

        强类型枚举的枚举值可以进行位操作,这在处理一组选项或标志时非常有用。可以使用位运算符(如|&~)对具有位模式的枚举值进行操作。

enum class Permissions : unsigned int {
    Read = (1 << 0),
    Write = (1 << 1),
    Delete = (1 << 2)
};

Permissions myPerm = Permissions::Read | Permissions::Write;
  • 自定义枚举值的整数值

        可以为强类型枚举的枚举值显式地设置整数值。这有助于与现有的枚举类型或其他库进行兼容。

enum class Result : int {
    Success = 0,
    Failure = -1
};
  • 枚举值的迭代

        可以通过static_cast将枚举类型转换为其潜在类型,然后进行迭代。这对于遍历枚举值的所有可能选项很有帮助。

enum class Size : int {
    Small = 1,
    Medium,
    Large
};

for (int i = static_cast<int>(Size::Small); i <= static_cast<int>(Size::Large); ++i) {
    // 处理每个枚举值
}
  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泽箬酱咧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值