八股文(四)

八股文(四),第1张

各种关键字

const

1首先知道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变量两个都可以走。函数重载的意思是函数的函数名,参数还有返回值都是一样的函数。

更深层次的理解是这样的:

因为在非const修饰的函数中,this指针也是非const的。在const修饰的函数中,this指针是const修饰的。

所以非const对象调用函数时,this指针是非const的,调用非const函数。const对象调用函数时,this指针是const的,调用的是const的函数。
 

static

static这个关键字引入的目的是用来调节变量的生命周期的,一般一个变量的生命周期从函数的作用域开始到作用域结束,但有时候还想在下面调用到这个变量,如果使用全局变量会影响变量的访问范围,所有就引入的static这个 关键字。这个时候变量属于类不属于函数。

static修饰的变量只能构造一次,初始化一次,且构造完后外部不能再调用。

static如果用来修饰函数,和上面的const有点像的是,返回的必须也是静态的变量,且只能修改调用静态变量

 static作用在普通函数和普通变量前时,可以避免重定义的问题,加了static只能这个函数、变量只在这个文件下面起作用。

在修饰成员函数和成员变量的时候,一个类中只有这一份,不需要生成对象就可以访问该成员,所有成员共享这一份,在修饰成员函数中,函数里面的变量也必须是静态成员变量。

static变量在类的声明中不占用内存,因此必须在.cpp文件中定义类静态变量以分配内存。全局变量、文件域的静态变量和类的静态成员变量在main执行之前的静态初始化过程中分配内存并初始化;局部静态变量在第一次使用时分配内存并初始化

extern

extern关键字有两个作用,一个是加在函数或者变量前面,表示这块函数或者变量的实现在其他的模块(也就是其他文件当中)寻找定义

接着在其他模块定义

 还有一个功能就是在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这个关键字,也是能自动推导类型的。

  1. 两者的区别在于auto不能用于函数传参和推导数组类型,但deltype可以解决这个问题。还有一个区别就是auto在使用的时候,在定义的时候必须同时对其进行初始化。这个是因为auto是通过之前的值推导出现在的值

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/797712.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-06
下一篇 2022-05-06

发表评论

登录后才能评论

评论列表(0条)

保存