各种关键字
const1首先知道const修饰符用来定义常量,具有不可变性 。
2然后还有引申出底层const和顶层const的概念,指针本身是个常量,指向的对象是常量,这样就有了顶层指针和底层指针的概念。顶层的const表示的是指针本身无法被修改位置,只能指向这个对象,底层的const表示的是指针指的对象是是常量,无法被修改值。
int i = 0;int *const p1 = &i; // 不能改变p1的值,这是一个顶层constconst int ci = 42; // 不能改变ci的值,这是一个顶层constconst int *p2 = &ci; // 允许改变p2的值,这是一个底层constconst int *const p3 = p2; // 靠右的const是顶层const,靠左的const是底层constconst int &r = ci; // 用于声明引用的const都是底层const
【C++100问】深入理解理解顶层const和底层cons - 云+社区 - 腾讯云 (tencent.com)
3.const来修饰函数,有两个功能,一个是限制函数修改成员变量,(这里的num是上面类的成员变量)
还有一个功能就是const修饰的函数可以实现重载
#include
using namespace std;
class Test
{
public:
Test();
~Test();
int num=2;
int fun();
int fun(int b) const;
int fun(int b);
};
Test::Test()
{
cout << "Test()" << endl;
}
Test::~Test()
{
}
int Test::fun()
{
cout << " int fun();" << endl;
return 0;
}
int Test::fun(int b)
{
cout << " int fun(int b);" << endl;
num = b;
cout << num;
return 0;
}
int Test::fun(int b) const
{
cout << " int fun(int b) const;" << endl;
return 0;
}
int main()
{
Test test;
const Test testC;
test.fun();
test.fun(3);
testC.fun(3);
system("pause");
return 0;
}
输出结果是
实现了函数重载,非const成员走非const修饰的函数,const成员走const修饰的函数,如果没有函数重载,被const修饰的成员函数,非const变量和const变量两个都可以走。函数重载的意思是函数的函数名,参数还有返回值都是一样的函数。
static更深层次的理解是这样的:
因为在非const修饰的函数中,this指针也是非const的。在const修饰的函数中,this指针是const修饰的。
所以非const对象调用函数时,this指针是非const的,调用非const函数。const对象调用函数时,this指针是const的,调用的是const的函数。
static这个关键字引入的目的是用来调节变量的生命周期的,一般一个变量的生命周期从函数的作用域开始到作用域结束,但有时候还想在下面调用到这个变量,如果使用全局变量会影响变量的访问范围,所有就引入的static这个 关键字。这个时候变量属于类不属于函数。
static修饰的变量只能构造一次,初始化一次,且构造完后外部不能再调用。
static如果用来修饰函数,和上面的const有点像的是,返回的必须也是静态的变量,且只能修改调用静态变量
static作用在普通函数和普通变量前时,可以避免重定义的问题,加了static只能这个函数、变量只在这个文件下面起作用。
在修饰成员函数和成员变量的时候,一个类中只有这一份,不需要生成对象就可以访问该成员,所有成员共享这一份,在修饰成员函数中,函数里面的变量也必须是静态成员变量。
static变量在类的声明中不占用内存,因此必须在.cpp文件中定义类静态变量以分配内存。全局变量、文件域的静态变量和类的静态成员变量在main执行之前的静态初始化过程中分配内存并初始化;局部静态变量在第一次使用时分配内存并初始化。
externextern关键字有两个作用,一个是加在函数或者变量前面,表示这块函数或者变量的实现在其他的模块(也就是其他文件当中)寻找定义
接着在其他模块定义
还有一个功能就是在C++编译器里使用C 的方法来写的函数的代码,为了方便,如果函数很多的化,可以拉个大括号在直接放进去
#pragma once
#ifdef __cplusplus
extern"C"{
#endif
#include
void show();
#ifdef __cplusplus
}
#endif
--------
再学下一个关键字前先来学一下初始化列表,这个经常在构造函数的时候出现,但经常看不出来。
初始化列表需要知道的几个点是1使用的时候程序运行效率会更高.2这两种情况是不能用的,一种是成员变量带有const还有一种是成员变量带有引用,就是引用成员。3在继承的时候,子类也常常通过初始化列表来进行初始化父类成员
写法就大概是这样
class fraction {
public:
fraction(int a, int b) :x(a), y(b) { }
int x;
int y;
};
int main(){
fraction s(2,3);
cout << s.x << s.y;
}
explicit用到的地方挺少的,一般就是在构造函数前面才用到,为了就是避免函数隐式转换。说明函数是显示 的
constexpr关键字用处就是让编译器知道这个一个常量,以便其方便进行大胆的优化。常量基本可以当作是无修改的变量
volatile关键字(这个暂时还没掌握)跟编译器优化有关,告诉编译器每次 *** 作该变量时一定要从内存中真正取出,而不是使用已经存在寄存器中的备份。
mutable关键字这个关键字只能对类的成员变量来使用。用处就是可以在const修饰的函数里对成员变量进行修改。
class a {
public:
mutable int A=3;
void test()const
{
A++;
}
};
目录
const
static
extern
explicit用到的地方挺少的,一般就是在构造函数前面才用到,为了就是避免函数隐式转换。说明函数是显示 的
volatile关键字(这个暂时还没掌握)
mutable关键字
auto关键字
auto的作用就是用来自动推导类型的,用自动转化有利有弊。有时候想知道具体是什么类型,有时候这样会便捷,不需要每次都进行类型的改变。
mapperson;
person["ok"] = 18;
person["nok"] = 19;
//map::iterator it;
for (auto it = person.begin(); it != person.end(); it++) {
cout << it->second<first;
}
然后还有另一个关键字也能起到和auto一样的作用,deltype这个关键字,也是能自动推导类型的。
- 两者的区别在于auto不能用于函数传参和推导数组类型,但deltype可以解决这个问题。还有一个区别就是auto在使用的时候,在定义的时候必须同时对其进行初始化。这个是因为auto是通过之前的值推导出现在的值
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)