const volatile mutable constexpr

一、const

指针常量与常量指针

去掉const限定(类型退化)

const_cast

2. const在不同位置的作用

const int fun(); 函数返回值为 const

int fun(const int arg); 参数arg在函数内不可修改

int fun() const;函数为只读函数,这个函数不能访问所有this所能调用的内存,不能对类对象的数据成员(准确说是非静态数据成员)做任何改变

const和constexpr修饰指针
constexpr int x = 110;

int main()
{
    const int* p1 = nullptr;            //p1是一个指向常量的指针,指针本身是变量
    constexpr int* p2 = nullptr;        //p2是一个指向变量的常量指针,指针本身是常量
    constexpr const int* p3 = nullptr;  //p3是一个指向常量的常量指针
    const int* const p4 = nullptr;      //p4是一个指向常量的常量指针

    p1 = &x;    // 正确,x是常量
    //*p1 = 2;  // 错误
    //p2 = &x;  // 错误
    *p2 = 2;    // 正确
    //p3 = &x;  // 错误   
    //*p3 = 2;  // 错误
    //p4 = &x;  // 错误
    //*p4 = 2;  // 错误

    return 0;
}

3. 常量(即const)对象

可以调用const成员函数,不能调用非const修饰的函数,非const对象既可以调用const成员函数,也可以调用非const成员函数

点击查看代码
#include <iostream>

class A
{
public:
    void Func1() const
    {
        std::cout << "func1\n";
    }
    void Func2()
    {
        std::cout << "func2\n";
    }
    const int Func3()
    {
        std::cout << "func3\n";
        return 1;
    }
    void Func4(const int n)
    {
        std::cout << "func4\n";
    }
};

int main()
{
    const auto a1 = A();
    auto a2 = A();

    a1.Func1();    // 正确
    //a1.Func2();  // 错误
    //a1.Func3();  // 错误
    //a1.Func4(0); // 错误

    a2.Func1();
    a2.Func2();
    a2.Func3();
    a2.Func4(0);
}

4. const用于重载

转载出处

点击查看代码
#include <iostream>

int f1(char* x)
{
    return 1;
}

int f1(const char* x)
{
    return 2;
}

int main()
{
    char s1[] = "aaa";
    const char s2[] = "bbb";

    std::cout << f1(s2) << std::endl;

    return 0;
}

二、volatile

转载自:详解C/C++中volatile关键字
volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。

为了安全起见,只要是等待别的程序修改某个变量的话,就加上volatile关键字。

一般说来,volatile用在如下的几个地方:

  1. 中断服务程序中修改的供其它程序检测的变量需要加volatile;

  2. 多任务环境下各任务间共享的标志应该加volatile;

  3. 存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;

三、mutable

四、constexpr

const expression 常量表达式

c++11规定:允许将变量声明为constexpr类型,以便由编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化

一般来说,如果你认定变量是一个常量表达式,那就把它声明成constexpr类型。

constexpr int n1 = 20;     //20是常量表达式
constexpr int n2 = n1 + 1; //n1+1是常量表达式
constexpr int n3 = size(); //只有当`size()`是一个constexpr函数时才是一条正确语句

五、const和constexpr的区别

const表示的是变量只读,注意是变量,constexpr表示的是常量,在编译期就能确定值

点击查看代码
#include <iostream>
using namespace std;
int main()
{
    int a = 10;
    const int & con_b = a;
    cout << con_b << endl;
    a = 20;
    cout << con_b << endl; // 输出20,const修饰的con_b值被修改了
}

转载:C++11 constexpr和const的区别详解

五、检查类型是否为const或volatile限定,添加、移除const或volatile限定

    const int ic = 0;
    volatile int iv = 0;
    std::cout << std::is_const< decltype(ic)>::value;//1
    std::cout << std::is_const<int>::value;//0
    std::cout << std::is_const<const int*>::value;//0
    std::cout << std::is_const<int* const>::value;//1
    std::cout << std::is_volatile<decltype(iv)>::value;//1
    std::cout << std::is_volatile<int>::value;// 0
    std::is_const<const int>::value_type Bool;//Bool是一个没有初始化的bool型变量
    std::is_const<const int>::type;
    std::remove_const<const int>::type Int;//Int是一个没有初始化的int型变量
    std::remove_cv<const volatile int>::type CV;//CV是一个没有初始化的int型变量

    int i = 0;
    auto&& ret1 = std::as_const<int>(i);//类型为const int&
    auto&& ret2 = std::as_const(i);//类型为const int&
    auto ret3 = std::as_const(i);  //类型为int

    std::add_const<int>::type CI = 0;  //CI是一个const int型且初始值为0的常量(const必须初始化)

原文链接: https://www.cnblogs.com/mmmmmmmmm/p/14088182.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    const volatile mutable constexpr

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/404231

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月24日 下午6:45
下一篇 2023年4月24日 下午6:45

相关推荐