c++primer学习笔记(3)-Compound Types(pointers and references) and const Qualifier.

1. The concept of Compound Types:

A compound type is a type that is defined in terms of another type, C++ has several compound types, two of which---references and pointers.

declarations consist of a type followed by a list of variable names----A declaration is a base type followed by a list of declarators. Each declarator names a variable and gives the variable a type that is related to the base type.

references and pointers in a declaration are called modifier.

2. references:

引用是一个变量的别名,没有地址,因此,不能定义引用的引用,如: int&& p = ....; 是不能表示引用的引用的,但是它却是另一个compound type, 叫做rvalue reference(右值引用)

一旦定义引用后,该引用的使用就相当于在使用原变量了,只是名字换了而已.

3. Pointers:

引用没有地址,因此,不能定义引用的指针,(int& *p)

指针的类型必须和所指向的变量名一致,除非是void* 类型

nullptr:  没有初始化的指针应该在C++11中应该赋值为nullptr, 表示没有指向任何对象

4. Compound Types:

1. Pointers to Pointers:

指针也是变量,所以可以定义指针的指针,但类型必须保持一致

2. references to pointers:

指针是变量,所以可以定义指针的引用.

int i = 1, *pi = &i;

int* &rp = pi;

在上面的定义中,我们从右往左读,首先,rp是一个引用,然后是一个int*,表示是一个int*的引用,相当于给pi取了一个别名。

5. const Qualifier:

1. const 在definition的时候必须被初始化.

2. By Default,  const Objects are local to file.即,const默认是只能在本地使用的,不像其他的类型:在其他文件中可以用extern来使用,但是在const中,一旦被初始化,编译器会在本地每个使用该const的地方替换为对应的值,所以不能在其他文件中使用。

3. 如何在其他文件中使用const呢?可以在definition的时候加上extern,如:extern const int a = 2; 表示该变量可以在其他文件中使用,然后如果想在其他文件中使用,只需要declaration就ok了,比如extern const int a;就可以使用了。

4. 需要注意的是,无论是const 还是 非const , 使用extern的时候都不能在函数中进行初始化。

6. references to const

1. 我们不能用一个非const的引用对一个const类型的变量进行引用(如:const int a = 10; int& c = a是错误的, 必须是const int& c = a才是正确的,因为a本身是不可改变的,所以也不能通过c来进行改变)

2. 当我们定义了一个const的引用:如const int &a, 的时候,我们可以用任何可以强制转化为const的表达式对a进行初始化,也就是说,我们可以定义一个const 的引用,指向一个非const的变量(即使类型不同),一个literal, 或者任何可以强制转化为const的表达式。如:

double b = 3.14;

const int &a = b;

上面的定义中,我们以前说过,引用和被引用的变量之间的类型必须一样,但是,这里有例外(以后还有另一个例外),就是当我们初始化一个const的引用的时候,那么上面的定义发生了什么呢?我们知道,a是一个指向int型的引用,为了保证这一点,编译器做了下面的事情来进行强制转化:

const int temp = b;

const int& a = temp;

编译器创建了一个临时的没有名字的变量,并且把这个变量和a进行绑定,考虑如果a不是const的话,那么a是绑定了一个编译器创建的空的变量,那么改变它是没有意义的,和我们想改变的结果b是不一样的。

7. pointers to const( low-level const) AND const pointers( top-level const )

1.pointers to const (直接用例子来说明了):

const double a = 3.14;

double b = 3.14;

double *test = &a; //错误

const double* p = &a;

p = &b; //正确:pointers to const 指的是所指向的那个变量的值不能改变,但是指针本身可以改变

*p = 2.2; //错误,p是一个指向const 的指针,所以不能改变所指向的值.

2. const pointers

int a = 0, b = 0;

int *const p = &a; //p必须被初始化,并且只能永远指向a,不能改变。

*p = 2;

p = &b; //错误

const double pi = 3.14159;

const double *const ppi = π//ppi是一个指向const的const pointer.

8. constexpr and literals types

constexpr是c++11新标准,为什么要定义它呢?有时候我们定义一个const类型的变量,并且希望初始化它的是一个常量表达式(const expression, 即能够在编译的时候就确定他的值), 可是有时候我们并不知道初始化它的到底是不是常量表达式,比如:const int sz = get_size(), 我们并不知道get_size()这个函数是否是一个const expression, 所以c++11引入了constexpr, 让编译器来帮我们检查,constexpr int a = 20*2*a*b; 它保证了,初始化a的一定是一个const expression。

由于constant expression 是在编译的时候被确定,所以能用constexpr修饰的类型只限于literal types(因为他们足够简单,能够有literal values), 常见的literal types有:arithmetic, reference, pointer, 不是literal types的有:class, library IO, string. 所以不能定义这些类型的constexpr, 

即使我们能定义pointer and reference为constexpr, 但是对他们的初始化确实很有限制的,比如:我们能用nullptr和0 literal来初始化constexpr pointer, 我们也能指向一个有固定地址的变量,然而,在函数内定义的变量一般都没有固定的地址,所以我们只能用在函数体外定义的变量(函数体外的变量有固定地址) 来初始化constexpr pointer.

9. Pointers and constexpr

constexpr 和 const 不一样,constexpr是top-level const, 而const是low-level const

const int *p = nullptr; // p is a pointer to a const int

constexpr int *q = nullptr; // q is a const pointer to int.

constexpr int *np = nullptr; //np is a const pointer to int that is null

int j = 0;

constexpr int i = 42; // type of i is const int

// i and j must be defined outside any function

constexpr const int *p = &i; // p is a constant pointer to const int i

constexpr int *p1 = &j; // p1 is a constant pointer to the int j;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值