第二章 语言可用性的强化——常量

第二章 语言可用性的强化——常量,第1张

第二章 语言可用性的强化——常量 2.1 常量 nullptr

目的是为了代替NULL。传统C++会把NULL、0视为一种东西,这取决于编译器如何定义NULL。有些编译器会定义为((void)* 0),有些会直接定义为0。

C++不允许直接将void 隐式转换到其他类型。如果编译器尝试把NULL定义为((void) 0),如下代码

char *ch = NULL;

由于C++没有 void * 的隐式转换,只好将NULL定义为0。表面上是解决了当前问题,但是这样做会产生重载混乱的新问题,如下代码:

void foo(char*);
void foo(int);
...
foo(NULL);  //这个函数会调用 foo(int),不符合直觉,很麻烦

C++11引入了nullptr关键字,专门用来区分空指针、0。nullptr的类型为nullptr_t,能够隐式的转换成任何指针或成员指针的类型,也能和它们进行相等或者不相等比较。

所以,作为新时代的C++程序员,请养成使用nullptr的习惯。

constexpr

C++中数组的长度必须是一个常量表达式,你可以以前通过如下代码也可以定义一个数组:

const int len = 10;
int arr[len] = { 0 };

上面的代码可能在大部分编译器上可以跑,但是其实在C++中这是非法的。如果用古老一点的编译器,是会报错的,但是现在的编译器大部分都做了优化,其实这一点非常的不好。

C++11引入了 constexpr关键字,让用户显示的声明函数或对象构造函数在编译期会成为常量表达式。而且,constexpr可以修饰递归,如下代码:

constexpr int fibonacci(const int n)
{
    return n == 1 || n == 2 ? 1 : fibonacci(n - 1) + fibonacci(n - 2); //斐波那契数列
}

int arr[fibonacci(4)] = { 0 };  //声明了一个有3个int元素的数组,每一个元素都是0

C++11引入的constexpr关键字只能修饰简单的函数,就是函数实现只能由 return 一行代码。从C++14开始,constexpr函数可以在内部使用局部变量、循环和分支等简单语句,如下代码:

constexpr int fibonacci(const int n)
{
    if (n == 1)
    {
        return 1;
    }

    if (n == 2)
    {
        return 1;
    }

    return fibonacci(n - 1) + fibonacci(n - 2);
}

和上面的那段代码功能一样,逻辑也是一样的,但是在C++11中是跑不了的。

注意事项

​1.constexpr 修饰符是将编译期运算的结果变成常量表达式,也就是说 constexpr 修饰的对象也要是一个确定不变的值,最起码需要是 const 修饰的值。如下代码:

int a = 1, b = 2;
const int c = 1, d = 2;
constexpr int value1 = a + b;  //错误,a 和 b 是变量,无法在编译期计算出常量值
constexpr int value2 = c + d;  //可以,c 和 d 是 const 常量,可以在编译期确定其值
constexpr int value3 = 1 + 2;  //更可以了

​2.如果是修饰函数,那么返回值一定不能是void ,也就是说一定要有返回值.

​3.C++11时期的constexpr有诸多限制,函数体通常只有一句 return 语句,函数体内既不能声明变量,也不能使用for语句之类的常规控制流语句。

​4.对于自定义类型(自定义类和自定义结构体),不能直接用constexpr修饰。正确的做法应该是在该类型的内部添加一个常量构造函数。如下代码:

struct myType
{
    constexpr myType(string name, int age):m_name(name), m_age(age) {};  //常量构造函数
    string m_name;
    int m_age;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5691562.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存