文档章节

const,constexpr,typedef,auto,decltype

枫城
 枫城
发布于 2016/07/07 22:55
字数 1200
阅读 11
收藏 0

const:

对变量的类型加以限定,使得变量在作用域内不可被修改。

默认状态下,const类型的对象仅在文件内有效。如果需要可以用extern帮助。

例:

// match.cpp定义并初始化一个常量PI,希望该常量能被其他文件访问

extern const double PI = 3.14159;

// match.h 头文件 声明PI

extern const double PI;

这样需要PI常量的地方添加,match.h头文件。

 

const的初始化: 定义一个常量时必须初始化。

1、编译时初始化: const int bufSize = 512;

2、运行时初始化: const int bufSize = getSize();

const常量在编译时的处理:会出现“常量折叠”。 折叠优化是和编译器相关的,可以设置。

例对于 const int bufSize = 512; 编译器会在编译过程中将所用用的bufSize的地方替换成512。所以编译器必须知道变量的初始值,及每一个使用它的地方都需要访问到它的初始值。

有问:对于运行时初始化:const int bufSize = getSize(); 会是怎样的啊?

运行时常量可以储存复杂对象,运行时常量需要在运行时进行初始化,需要保证常量在被使用前已经被初始化,一般是在类的构造函数或者初始化函数中进行初始化。

例:

#include <iostream>
#include "string.h"
using namespace std;
const double PI = 3.141593;
class Circle
{
public:
    Circle(double r): m_R(r)
    {
    }
    // const 对象不能调用非const函数
    double getArea() const
    {
        return PI * m_R * m_R;
    }
private:
    double m_R;
};
int main()
{
    const Circle oCircle1(1.0);
    cout << "Area : " << oCircle1.getArea() << endl;
    Circle oCircle2(1.0);
    cout << "Area : " << oCircle2.getArea() << endl;
    return 0;
}
 

 

结果:

const函数:  

    一般放在函数体后,形如:void   fun()   const;

    如果一个成员函数的不会修改数据成员,那么最好将其声明为const,因为const成员函数中不允许对数据成员进行修改,如果修改,编译器将报错,这大 大提高了程序的健壮性。

    const类型的对象只能使用const类型的函数,因为普通函数可能会尝试修改const的值。

 

指针常量和常量指针:

#include <iostream>
#include "string.h"
using namespace std;
int main()
{
    int a = 5;
    int b = 10;
    // p1 和 p2 相同; int const 和 const int 相同。
    int const* p1 = &a; // 常量指针 : 指向一个int类型常量的指针
    const int* p2 = &b; // 常量指针偏向指针的属性,可以指向不同的地址,但是不能通过指针改变值。
    p1 = &b; // 正确 常量指针可以改变指向的地址
    // *p1 = 20; // 错误 常量指针不可以改变指向的地址的值
    int* const p3 = &a; // 指针常量 : 指向一个int类型的常量指针
    // p3 = &b; // 错误 指针常量不可以修改指向地址
    *p3 = 30; //正确 指针常量可以修改指向地址的值。
    cout << "p1 : " << *p1 << endl;
    cout << "p2 : " << *p2 << endl;
    cout << "p3 : " << *p3 << endl;
    return 0;
}

结果: 

constexpr:

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

constexpr int mf = 20;           // 20 是常量表达式
constexpr int limit = mf + 1;    // mf + 1是常量表达式
constexpr int sz = size;         // 只有当size是一个constexpr函数时
                                 // 才是一条正确的声明语句

 ———— 摘抄自 C++ Primer

一个constexpr指针的初始值必须是:0或者nullptr,或者是存储于某个固定地址中的对象。 constexpr只对指针有效;

 

typedef:

    类型别名(type alias),就是给一个类型起另一个名字,例: typedef int Index; 值得一提的是新的标准里using也能达到这样的效果,例: using Index = int;

auto:

    

    牛掰的新特性:auto,麻麻再也不用心我用了一个错误的类型去接值变成空指针了。

C++11的新标准中引进的auto关键字,让编译器替我们去分析表达式的类型。但是这样的话,给变量一个有意义的名字就是一件特别重要的事了,好吧,这一直都很重要。

例:

int a = 0;

int b = 1;

auto c = a + b;

c 就自动推动成int类型, 呜哈哈。。

decltype:

这个我第一次见,这货是C++11 引进的第二个类型说明符,它的作用是选择并返回操作数的数据类型。编译器分析表达式并得到它的类型,但不会进行实际的计算。

例:

#include <iostream>
#include "string.h"
using namespace std;
int getsize(const string &value)
{
    return value.size();
}
int main()
{
    decltype(getsize("")) nSize = getsize("hello world !");
    cout << nSize;
    return 0;
}

 

© 著作权归作者所有

枫城
粉丝 0
博文 2
码字总数 1988
作品 0
崇明
程序员
私信 提问
【C++笔记】变量和基本类型

变量和基本类型(C++Primer 5th) 字符型   分为三种:char、signed char 和 unsigned char 。char 和 signed char并不一样,但字符的表现形式只有两种:带符号的和无符号的。 有符号与无符...

u013165921
2017/11/14
0
0
C++11 & C++14 & C++17新特性

原文:https://www.cnblogs.com/guxuanqing/p/6707824.html C++11:C++11包括大量的新特性:包括lambda表达式,类型推导关键字auto、decltype,和模板的大量改进。 新的关键字 auto C++11中引...

炎林2018
2018/12/06
0
0
C++11简摘

C++11特性: 1、右值引用,move 2、泛化的常数表示,constexpr 3、外部模板,extern 4、初始化列表,std::initializer_list<> 5、统一的初始化,{} 6、类型推导,auto,decltype 7、范围for...

悠米海
2016/08/27
3
0
C++ 不是 C 的一个超集:C++ 11 特性

这是很久之前的笔记,整理发出来并加了一点更新。 虽然C程序能用C++编译器编译,但是严格来说,C++ 不是 C 的一个超集。《为什么说C++不是C的超集? - 知乎》 这里有网友的解答,不再赘述。 ...

ypingcn
2017/09/12
0
0
Effective C++: auto类型推断.

1,请牢牢记住一点auto的推断其实是跟template的推断基本一致也有稍微的不同体现在std::initializer_list: 2,不能推断出一个模板中的另一个模板的类型(template<template<typenaem T> class ...

SHIHUAMarryMe
2016/03/30
133
0

没有更多内容

加载失败,请刷新页面

加载更多

android 事件分发

记录下对Android事件分发的理解: 如果a作为viewgroup,b作为view,b包含在a中。事件会先传递到viewgroup中,既a。然后a会进行事件分发给子view。事件分发的方法中,会有个判断,是否要分发给...

醉雨
23分钟前
0
0
今天的学习

今天学到了 get和post传参: Post传输数据时,不需要在URL中显示出来,而Get方法要在URL中显示 Post传输的数据量大,理论上是无限大,而Get方法由于受到URL长度的限制,只能传递大约1024字节 ...

墨冥
29分钟前
0
0
输入一颗二叉树的跟节点和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。

public class Solution { private ArrayList<ArrayList<Integer>> listAll = new ArrayList<ArrayList<Integer>>(); ArrayList<ArrayList<Integer>> all= new ArrayList<ArrayList<Integer>>......

南桥北木
31分钟前
1
0
使用lombok编写优雅的Bean对象

使用java编写代码,十之八九都是在写java类,从而构建java对象。lombok之前也说了不少,但使用了这么多年,感觉还是有很多技巧可以使用的。 毫无疑问,使用lombok,编写的java代码很优雅,而...

polly
32分钟前
1
0
表现与数据分离、web语义化的理解

表现与数据分离 什么是表现与数据分离? “分离”说的是两方面: 第一方面是前端与后台分离,所有数据都是后台通过AJAX发送给前端,前端处理数据展现页面,不需要后台在页面中插入变量。 第二...

祖达
39分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部