栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++ 基础与深度分析 Chapter2 对象与基本类型(常量、类型别名、域与对象的生命周期)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++ 基础与深度分析 Chapter2 对象与基本类型(常量、类型别名、域与对象的生命周期)

文章目录
  • 常量类型与常量表达式
    • 常量指针
    • 常量引用
  • 类型别名与类型自动推导
    • 类型别名
    • 类型自动推导
  • 域与对象的生命周期

常量类型与常量表达式 常量指针

int main()
{
    const int x = 3;
    std::cout << x << 'n';
    x = 6; // error: cannot assign to variable 'x' with const-qualified type 'const int'
}

常量x在初始化的时候完成了写操作,之后x的生命周期内,再也不能进行写操作了。
对变量的读和写,是对内存的读和写,所以是有底层硬件支持的。但是常量没有硬件支持,它是由编译器来保证的。定义一个常量,如果常量错,编译器就会报错。
在底层常量和变量都是对应一块内存,但是如果定义了常量,当要写操作常量时,那么编译器就会报错。
为什么要使用常量呢,为什么要防止写操作呢。编译器会防止非法操作。

还有就是常量可以优化程序逻辑。


如果确定一个变量声明后,不会再被修改,就把它设置成常量。

常量指针:如果一个指针的const,那么表明这个指针只能指向定义的变量,不能指向其他。

int main()
{
    int x = 4;
    int* const ptr = &x; // ptr只能指向x,不能在指向其他变量
    
	int y = 5;
    ptr = &y; // error: cannot assign to variable 'ptr' with const-qualified type 'int *const'
}

注意,上面const如果在int后面,是限制指向的对象不能修改。但是如果const在int之前,就是限制指向的对象的内容不能修改。

int main()
{
    int x = 4;
    const int* ptr = &x;
    x = 5;
    std::cout << x << 'n'; // 5
    *ptr = 10; // error: read-only variable is not assignable

	int y = 10;
    ptr = &y;
    std::cout << *ptr << std::endl; // 10,ptr指向对象的内容不能发生改变,但是可以改变指向的对象

}


记忆方法,如果const在*的右边,那么ptr本身不能改变,也就是不能改变指向的对象。

如果const在*的左边,那么ptr指向的内容不能改变。


顶层常量,只是限制指针本身(指向的对象)不能修改。底层常量,限制指向指向的内容不能修改。


常量引用

int main()
{
    int x = 3;
    const int& ref = x;
}

常量引用主要用于函数的形参

常量引用放在形参,主要是因为Str的复制成本高,如果形参是一个int或者其他内置类型,那么常量引用,变得画蛇添足。


#include 
#define constexpr const

int main()
{
    constexpr int y = 3;
}


constexpr const int* ptr等价于在底层和顶层都是const。

类型别名与类型自动推导 类型别名


比较旧的类型别名的引用:

typedef int Myint;
int main()
{
    Myint x = 3;
}

新的类型别名的引用:

using Myint = int;
int main()
{
    Myint x = 3;
}

老师推荐用using,不用typedef。
注意类型别名与指针的关系,当我们用类型别名定义一个指针的时候,应将指针的类型别名视作一个整体,那么这个指针是一个常量,而不是指针指向的内容是一个常量。

类型自动推导




典型的类型退化,int引用退化成int。cpp内建数组会退化成指针。auto会产生退化,

#include 
#include 

int main()
{
    auto x = 3;
    // 1 x是int类型
    std::cout << std::is_same_v << std::endl;
    const auto y = 100;
    // 0 y是const int类型
    std::cout << std::is_same_v << std::endl;
}


x是const int,但是当x放在=右边时,会退化成int。


decltype和auto的区别,decltype不会产生类型退化。

#include 
#include 

int main()
{
    int x = 3;
    int& y1 = x;

    auto y2 = y1;
    decltype(y1) y3 = y1;

    // 1 y2是int类型
    std::cout << std::is_same_v << std::endl;

    // 1 y3是int引用
    std::cout << std::is_same_v << std::endl;    
    
}

decltype如果是左值,会自动加上一个引用。

decltype里面是一个变量名称,那么一定会推到成这个变量。



#include 
#include 

int main()
{
    decltype(3.5 + 15l) x = 3.5 + 15l;
    //  等价于下面的,c++14
    decltype(auto) y = 3.5 + 15l;

}

auto替换成等号右边,在进行计算。

域与对象的生命周期


一个程序可以划分为若干个域。

不属于函数和类,在最外面,就是全局域。
大括号限定的域,就是局部域。
系统会优先选择局部域。

生命周期,起始于初始化,终止于被销毁。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/954385.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号