c++ ---const,内联函数

一、const修饰类成员
const修饰形参,一般和引用同时使用
const修饰返回值
const修饰类数据成员,必须在构造函数的初始化列表中初始化
(1)c语言和c++的区别:
1,、
A、在C语言中const修饰的变量具有常属性,但仍然为一个变量。在C语言环境下编译下述代码,会出现错误:
 
int main()
{
 const int a= 20;
 int array[a];
 return 0;
}

说明在C语言中const定义的变量仍然是一个变量。
但是在c++中,执行上述代码,结果不会产生错误,说明在c++中const定义的变量是一个常量。
B、
在c++中执行代码:
 
int main()
{
 const int a= 20;
 int *pa = (int *)&a;
 *pa = 10;
 printf("%d\n", a);
 printf("%d\n", *pa);
   return 0;
}

结果:

在c++中const修饰的变量,不仅是一个常量,还具有宏的特性,是一个宏常量,const定义的常量在程序编译的期间进行替换,可以进行类型检测,代码更安全。如果宏在预处理期间替换不会进行类型检测。
而在C语言中,执行上述代码后,结果为两个10.
2‘、
const修饰成员变量
在C++中,const既可以修饰普通的变量,还可以修饰类成员,如果修饰成员变量,必须将变量放在初始化列表的位置,进行初始化。
 
class Test
{
public:
 Test()
  :_a(a)
 {}
private:
 const int _a;
};
int main()
{
 Test t;
 return 0;
}

const修饰类中的成员函数:const修饰类成员函数,实际修饰隐含的this,表示在类中不可以对 类的任何成员(除了静态成员)进行修改
const修饰成员函数,把const放在函数体后面的位置,称为const类型的成员函数
 
class Test
{
public:
 //const Test *const
 void FunWithConst()const
  //所指向空间的内容不可以改变,指向的方向也不可以改变
  //const成员函数,内部不可以给成员变量赋值
 {
  cout << _data << endl;//可以读,不可以写
  //this->data=10;//编译时会出现错误
  _count = 22;//静态成员变量不需要借助this指针,可以对静态成员变量进行修改
 }
 //Test *const
 void FunWithoutConst()
  //指针指向空间中的内容可以改变
  //普通成员函数,内部可以给成员变量赋值
 {
  this->_data = 10;
 }
private:
 int _data;
 static int _count;
};
int Test::_count = 0;//静态成员变量必须在类外进行定义,且定义时不用加const
int main()
{
 return 0;
}

在const修饰的成员函数中要对类的某个数据成员进行修改,该数据 成员定义声明是必须加mutable关键字(普通成员变量在const定义的成员变量中修改不了,加上mutable关键字即可)
 
class Test
{
public:
 void FunWithConst()const
  {
  _data1 = 30;
 }
private:
  mutable int _data1;
 };
 int main()
{
 return 0;
}

(2)问题:
A、const对象可以调用非const成员函数和const成员函数吗?
const对象不可以调用非const成员函数,可以调用const成员函数(const对象定义的函数体里面不能对当前对象进行修改)
 
int main()
{
 const Test t;
 t.FunWithConst();
 //t.FunWithoutConst;
 return 0;
}

B、 非const对象可以调用非const成员函数和const成员函数吗?
非const对象可以非const成员函数,也可以调用const成员函数。
 
int main()
{
 Test t;//t是可读可写的
 t.FunWithConst();//只读 
 t.FunWithoutConst;//FunWithoutConst函数本身就是可读可写的,可以调用
 return 0;
}

C、 const成员函数内可以调用const成员函数和非const成员 函数吗?
 const成员函数内可以调用const成员函数,但是不能调用非const成员函数(普通成员函数)
 
 //const Test *const//只读
 void Test1()const
 {
  FunWithConst();//const Test *const
  FunWithoutConst();//Test *const//可读可写
 }
private:
 int _data;
 static int _count;

D、 非const成员函数内可以调用const成员函数和非const成 员函数吗?
非const成员函数内可以调用const成员函数,也可以调用非const成 员函数
 
//Test *const//可读可写
	void Test1()
	{
		FunWithConst();//const Test *const//可读
		FunWithoutConst();//Test *const//可读可写
	}
private:
	int _data;
	static int _count;

const修饰的实际是this指针,普通成员函数修改不了。
(3)&操作符
若是只下面的代码,只能给构造普通成员函数,而不能构造const定义的成员函数
 
class Test
{
public:
 //const Test *const
 void FunWithConst()const
  //所指向空间的内容不可以改变,指向的方向也不可以改变
  //const成员函数,内部不可以给成员变量赋值
 {
  cout << _data << endl;//可以读,不可以写
  //this->data=10;//编译时会出现错误
  _count = 22;//静态成员变量不需要借助this指针,可以对静态成员变量进行修改
 }
 //Test *const
 void FunWithoutConst()
  //指针指向空间中的内容可以改变
  //普通成员函数,内部可以给成员变量赋值
 {
  this->_data = 10;
 }
 Test *operator&()
 {
  return this;
 }
private:
 int _data;
 static int _count;
};
int Test::_count = 0;//静态成员变量必须在类外进行定义,且定义时不用加const
int main()
{
 const Test t1;
 Test t2;
 cout << &t1 << endl;
 cout << &t2 << endl;
 return 0;
}

若是要构造const定义的成员函数,入下:
 
 Test *operator&()
 {
  return this;
 }
               const Test *operator&()const
 {
  return this;
 }
构造函数不能用const修饰,为什么?
class Test
{
public:
	Test()const
	{}
	 
};
此时编译器会报错:const修饰类的成员函数,实际上就是在修饰当前对象,构造函数没有调用,则当前对象不存在,也就不能修饰构造函数的指针,只知道一块空间的位置,初始化列表没有执行。没有初始化,不知道当前对象具体占了几个字节。a、构造函数没有执行,当前对象不存在;b、构造函数里面,创建成功之后需要放一些初始值,用const对象修饰以后不能给对象放初始值。

二、内联函数:
1、以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数 的地方展开(替换掉,内联函数替换发生在编译器编译的阶段而宏替换发生在预处理阶段),没有函数压栈的开销,内联函数提升程序运行的效率

inline int Add(int left, int right)
{
	return left + right;
}
int main()
{
	int a = 10;
	int b = 20;
	int c=Add(a, b);
	return 0;
}
处于调试状态下,不会进行替换,替换后,因为不能进行调试。此时想要进行替换可以:a、项目--常规--调试信息格式---程序数据库;优化---O(1)、只适用于inline
此时不会出现函数调用,编译期间就进行了替换。

2、说明:

(1)inline是一种以空间换时间的做法,省去调用函数额开销。所以代码 很长或者有循环/递归的的函数不适宜使用内联,可以提高运行效率。

(2)inline对于编译器而言只是一个建议,编译器会自动优化,如果定义 为inline的函数体内有循环/递归等等,编译器优化时会忽略掉内联

inline int Add(int left, int right)
{
	Add(left,right);
	return left + right;
}
int main()
{
	int a = 10;
	int b = 20;
	int c=Add(a, b);
	return 0;
}

函数自己调用自己时会出现递归,即使加上inline,也不会被编译器当成内联函数。满足内联函数的处理条件,编译器才会把此函数当成内联函数处理。

(3)inline必须函数定义放在一起,才能成为内联函数,仅将inline放在 声明前是不起作用的,如下程序:

inline int Add(int left, int right);
int Add(int left, int right)
{
	Add(left, right);
	return left + right;
}
int main()
{
	int a = 10;
	int b = 20;
	int c = Add(a, b);
	return 0;
}

(4)定义在类内的成员函数默认定义为内联函数

class Test
{
public:
	Test(int data=1)
	{
		_data = data;
	}
	int _data;
};
int main()
{
	Test t;
	return 0;
}
看不到构造函数的调用, 在类内的成员函数默认定义为内联函数 ,编译时已经展开了

注:在C++中,强制建议使用const代替宏常量,使用内联函数代替宏函数, const和内联函数在进行编译时不仅进行替换,而且还会进行参数类型检测,提高了程序的安全性。内敛函数可以是普通函数,也可以是类的成员函数;函数式宏不能作为类的成员函数(宏只是预处理阶段产生的)。

(1)普通成员变量与静态成员变量的区别:

a、普通成员变量,每个类对象都有,静态成员变量所有对象共享(只有一份),sizeof计算时,不计算静态成员变量的大小

b、普通成员变量不用拿到类外定义,静态成员变量需要在类外进行定义,类里面只是相当于一个声明

c、普通成员变量可以直接在普通成员函数中使用;静态成员变量也可以在普通成员函数中使用

d、静态成员函数中可以访问静态成员变量,而不能访问普通成员变量(访问普通成员变量需要借助this指针,但是静态成员函数里面没有this指针

e、对于普通成员变量:公有的成员可以在内外进行访问,访问时,必须通过对象进行访问;对于静态成员变量公有的成员可以在内外进行访问,访问时,只需要通过类名

普通成员函数和静态成员函数的区别:

a、普通成员函数参数列表里面有一个隐藏的this指针,而静态成员函数中没有this指针

b、普通成员函数可以调用静态成员函数,静态的成员函数也可以调用静态成员函数

c、普通成员函数可以调用普通成员函数,静态成员函数不可以调用静态成员函数

d、普通成员函数可以通过对象调用,静态成员函数只用类的作用域加上函数的名字即可:Test::函数名()

const类成员:

const修饰成员变量和普通成员变量的区别:

a、const修饰的成员变量,不能修改,普通变量可以修改

b、const修饰的成员变量必须放在初始化列表中进行初始化,而普通变量没有说明

c、const修饰的成员变量可以修饰成员函数(const类型的成员函数),const关键字出现在函数体的后面【特性:函数体里面不能修改普通的成员变量,因为const修饰的是this指针】)


问题:一个常规的成员函数声明描述了三件在逻辑上相互不同的事情:

该函数能访问类声明的私有部分

该函数位于类的作用域之中 

该函数必须经由一个对象去激活(有一个this指针)【函数要调用只能通过一个对象去调用】
通过将函数声明为static,可以让它只有前两种性质   通过将一个函数声明为友元可以使它只具有第一种性质。
一个成员函数用static修饰,就成为了一个静态成员变量。友员函数不是类的成员函数,不在类的作用域里面,不用通过类的作用域来调用。友员函数可以访问类的私有部分。

猜你喜欢

转载自blog.csdn.net/xuruhua/article/details/80743460