C++ 学习笔记
typedef推导
typedef int T;
T a;
- 将
typedef
去掉,将T
换成a
,即可得int a
,所以表示a
是int
类型;
typedef char* T;
T a;
- 将
typedef
去掉,将T
换成a
,即可得char* a
,所以表示a
是char*
类型;
typedef struct { int b; } T;
T a;
- 将
typedef
去掉,将T
换成a
,即可得struct { int b; } a
,所以表示a
是struct { int b; }
类型;
typedef int (*T) (int, int);
T a;
- 将
typedef
去掉,将T
换成a
,即可得int (*a) (int, int)
,所以表示a
是int () (int, int)
的函数指针类型;
typedef int* T (int, int);
T a;
- 将
typedef
去掉,将T
换成a
,即可得int* a (int, int)
,所以表示a
是int* () (int, int)
的函数类型; - 由于
int* a(int, int)
相当于只有声明,还必须再进行函数a
的定义,此时a
才能传参调用; - 或者直接用
T* a
,这样a
就是一个函数指针,不需要有具体的定义,可以用其指向同类型函数;
typedef int T (int, int);
T a;
- 同上
const修饰符
const
修饰其后第一个非类型的部分
const修饰变量、指针与引用
const int a = 5;
a = 6;
a
被const
修饰,因此a
为常量,即其值不可更改,于是上面的a=6
赋值操作会报错;a
不可改值,因此必须初始化;
int a[3] = {5, 4, 3};
const int* b = a;
a[0] = 6;
cout << a[0] << endl;
*b = 7;
cout << a[0] << endl;
*b
被const
修饰,于是*b=7
报错,同理b[1]=7
也会报错,但是a[0]=6
正常运行,因为*b
是不可变左值,但a[0]
是可变左值- 赋值或传参时,左值的访问权限只能小于或等于右值的访问权限
- 对于
int const *b
,const
仍然修饰*b
,于是同上
int a[3] = {5, 4, 3};
int* const b = a;
b[0] = 7;
int c[2];
b = c;
b
被const
修饰,于是b=c
报错,但是b[0]=7
正常运行,因为此时b
是常量,但*b
不是
int a = 5;
const int& b = a;
b = 4;
int& const c = a;
c = 3;
const
修饰的是b
引用的值,因此b=4
报错;const
修饰标识符c
,由于引用不可重新定向,即本身就是常量,因此此修饰无意义,c=3
可正常运行;
const修饰函数返回值
const int& fun(int& a);
const
修饰的是返回值,因此返回值不能被更改- 一般用在返回值为引用类型时,因为
const
只有修饰左值才有意义;当返回值为值类型时,const
修饰无意义; - 当返回值为引用类型时,一般是成员变量或函数参数,不应该是临时变量,因为一旦是临时变量,函数调用结束后,该变量内存空间被释放,其内容可发生任意改变,导致错误引用
const修饰类、成员函数
class A{
int a;
void const b() {
a = 1;
}
}
const
修饰的是返回值,虽然返回值为void
,仍然可以正常运行;
class A{
int a;
void b() const {
a = 1;
}
}
const
修饰的是成员变量,因此a=1
报错;
class A{
int a;
void b(){
cout << a << endl;
}
}
const A c;
c.a = 1;
c.b();
c
被const
修饰,因此c
不可更改任何成员变量,亦不可调用任何非const
成员函数
class test {
int a = 0;
public:
void fun1() {
a = 1;
cout << a << endl;
}
void fun2() const {
cout << a << endl;
}
};
int main()
{
test A;
A.fun1();
A.fun2();
const test B;
B.fun1();
B.fun2();
}
A.fun1()
、A.fun2()
与B.fun2()
都能正常运行,但是B.fun1()
报错,报错信息为
void test::fun1(void)': cannot convert ‘this’ pointer from ‘const test’ to ‘test &’
- 即类中非
const
成员函数中使用的this
指针为T *
类型,但是对const
修饰的类,指向其的指针应为const T *
类型,因此,const
类调用非const
成员函数,将发生类型转换,并因转换不成功报错;而类中const
成员函数使用的this
指针本身就是const T *
类型,因此不会产生此种报错。
const类与构造函数
Unlike other member functions, constructors may not be declared as const. When we create a const object of a class type, the object does not assume its “constness” until after the constructor completes the object’s initialization. Thus, constructors can write to const objects during their construction.
- 构造函数不能被声明为
const
类型,因此当一个类实例被声明为常量时,只有在构造函数完成该对象的初始化之后,该对象才成为不可变的。